I've got a program that I'm finishing up that is a name generator. Right now it takes a random value from 2 separate arrays, concatenates them and displays the result as the label. text -- I want to have a button that reverses the label text (instead of John Doe, it would say Doe John). This is the code I'm using to do this. My thinking is that I use the same values from the arrays and then assign the string to a variable for use later in another method called "reverseNameValue" or something. It's not working :) When I click the "reverse" button, it shows me a different name altogether. Any advice?
- (IBAction)generateBName:(id)sender {
int a = arc4random() % 3;
int b = arc4random() % 3;
// populate the array for the names
NSArray *firstNameArray = [NSArray arrayWithObjects: #"Jacob",
#"Ethan",
#"Justin", nil];
NSArray *middleNameArray = [NSArray arrayWithObjects: #"Jose",
#"Jeremiah",
#"Julian", nil];
// concatenate strings at index of array
NSString *fullName = [NSString stringWithFormat:#"%# %#", [firstNameArray objectAtIndex:a], [middleNameArray objectAtIndex:b]];
NSString *reverseName = [NSString stringWithFormat:#"%# %#", [firstNameArray objectAtIndex:b], [middleNameArray objectAtIndex:a]];
// display the newly created first & middle names
reverseNameString = reverseName;
babyname.text = fullName;
And the reverse method:
- (IBAction)reverseLabel:(id)sender {
babyname.text = reverseNameString;
}
the line where you set the reverseName string has the names backwards, so it is grabbing a firstname and then a middlename but with reversed indexes. It should be:
NSString *reverseName = [NSString stringWithFormat:#"%# %#", [middleNameArray objectAtIndex:b],[firstNameArray objectAtIndex:a]];
Related
I have an array that contains all the names that I get from JSON
NSArray *name = [newResponseObject valueForKey:#"name"];
I also have another array that contains all the last names that I get from JSON.
NSArray *lastname = [newResponseObject valueForKey:#"lastname"];
What I want to do achieve is creating another array that contains [name, lastname] and I want to display the values for my picker view. for example "John Smith".
I have tried using arrayWithArray but that just added all the values into one array.
What is the correct method to achieve this ?
Depending on what you're planning on doing with them afterwards should dictate how you decide to store them. As #Woodstock mentioned you can store them in an array of concatenated strings "name lastname" similar to option 1 from below.
But from your description it sounds like you may want to store them as an array of arrays similar to option 2 from below.
// option 1 storing them in concatonated strings
NSArray *firstNames = #[#"John", #"Ralph", #"Bob"];
NSArray *lastNames = #[#"Smith", #"Jones", #"Miller"];
NSMutableArray <NSString *> *firstAndLastNames = [NSMutableArray array];
for (NSInteger index = 0; index < firstNames.count; index++) {
[firstAndLastNames addObject:[NSString stringWithFormat:#"%# %#", [firstNames objectAtIndex:index], [lastNames objectAtIndex:index]]];
}
NSLog(#"First and last names = %#", firstAndLastNames);
// option 2 storing them in arrays
NSMutableArray <NSArray *> *firstAndLastNamesInArray = [NSMutableArray array];
for (NSInteger index2 = 0; index2 < firstNames.count; index2++) {
[firstAndLastNamesInArray addObject:#[[firstNames objectAtIndex:index2], [lastNames objectAtIndex:index2]]];
}
NSLog(#"First and last names in array = %#", firstAndLastNamesInArray);
Which would result in outputs of:
Option 1:
First and last names = (
"John Smith",
"Ralph Jones",
"Bob Miller"
)
Option 2:
First and last names in array = (
(
John,
Smith
),
(
Ralph,
Jones
),
(
Bob,
Miller
)
)
The benefit of using the second option is if you want to just get the first name or last name you can just find it by index (rather than having to attempt to separate the first and last names by space -- some first or last names also have spaces in them so this could mess up your logic of trying to fetch just one of the names if you use option 1).
i.e. using option 2 you can find the last name of the 3rd person by doing this:
[[firstAndLastNamesInArray objectAtIndex:2] objectAtIndex:1]
Another option would be to create a Person object and have it have properties firstName and lastName and then store an array of Person objects instead.
One other thing you didn't mention as well (but I'm assuming is true), is are these arrays you're fetching from the server in the correct order -- i.e. does firstName[3] correlate with lastName[3]? Also are you always guaranteed to have a firstName and lastName for each person?
There are lots of ways to achieve this.
Probably the easiest is to concatenate at source.
NSArray *fullName = [NSString stringWithFormat:#"%# %#", [newResponseObject valueForKey:#"name"], [newResponseObject valueForKey:#"lastname"]];
I have a problem with my algorithm for calculating a sore. The user enters a word into the UITextField, and if the word matches a string in the array (#"The Word") the int 'score' will be added by 1.
Then the int score is set as a label as the user gets a word right. (DISPLAYING THE SCORE)
THE PROBLEM, a user can just keep on entering the same word over and over again and the score will keep going up by one. IS there a command for knowing if a word has already been entered, so you can only use the word once.
The Code
NSArray *scoreArray1 = [NSArray arrayWithObjects:
#"Word 1", #"Word 2", #"Word 3", nil];
NSString *inputtwo =_EnterNameText.text;
BOOL isItright = NO;
for(NSString *possible in scoreArray1) {
if([inputtwo isEqual:possible] ) {
isItright = YES;
break;
}
}
if(isItright) {
static int myInt = 0;
myInt++;
NSString *score = [NSString stringWithFormat:#"%d", myInt];
[_scorelabel setText:score];
}
UPDATE!!!!!!
NSArray *scoreArray1 = [NSArray arrayWithObjects:
#"Alan Shearer", #"Shearer", #"Andrew Cole", #"Andy Cole", #"Cole", #"Thierry Henry", #"Henry", #"Robbie Fowler", #"Fowler", #"Frank Lampard", #"Lampard", #"Michael Owen", #"Owen", nil];
NSSet *set2 = [NSSet setWithArray:scoreArray1];
NSString *inputtwo =_EnterNameText.text;
BOOL isItright = NO;
for(NSString *possible in set2) {
if([inputtwo isEqual:possible] ) {
isItright = YES;
break;
}
}
if(isItright) {
static int myInt = 0;
myInt++;
NSString *score = [NSString stringWithFormat:#"%d", myInt];
[_scorelabel setText:score];
}
HOWEVER NOW THE APP DOES NOT WORK, IT CRASHES, any suggestions?
Why don't you keep a second Array where you store the given (correct) answers.
Whit this you can just do a contains inside your if....problem solved.
a second option is not to put string in your array but "Answer" Objects, that have a field that you can flag as already used.
You could just create an NSMutableSet and put a copy of the word into there whenever one is entered. Then you just need to check if the word exists in the set before incrementing the score.
I'm suggesting a set because it uses hashed access, so lookups are fast. Also, if you add the same string more than once, the set will still only have one reference to the string.
Actually, if you have an array of "legal" words, the way to go is to simply remove each word as it's called out, until the array gets to be zero entries long.
NSMutableArray* scoreArrayCopy = [NSMutableArray arrayWithArray:scoreArray];
int originalCount = scoreArrayCopy.count;
...
while (scoreArrayCopy.count > 0) {
NSString* guess = <get next guess>;
[scoreArrayCopy removeObject:guess];
score = originalCount - scoreArrayCopy.count;
}
(If you have a lot of words things would be more efficient if you used an NSMutableSet instead of an NSMutableArray, but the logic would be the same.)
I'm making a code which shows the names of people on a list.
The list is different for each date, so my problem is when there is only like 1 or no people signed and I make an array with index beyond the limit of people, it crashed. I know that this happens because the array is empty, but how do I make the code ignore empty arrays?
I have tried to make an "if" that count the number of arrays and then decide to post the array or just post no name. But it doesn't work like this, I still get the out of bounds exception.
How should I manage empty arrays?
My code:
NSString *html = [request2 responseString];
NSMutableArray *arr2 = [html componentsSeparatedByString:#"vagter"];
NSString *html1 = [arr2 objectAtIndex:1];
//name1
NSMutableArray *arr3 = [html1 componentsSeparatedByString:#"<td><font color=#ffffff>"];
NSString *html2 = [arr3 objectAtIndex:1];
NSMutableArray *arr4 = [html2 componentsSeparatedByString:#"</font></td>"];
NSString *html3 = [arr4 objectAtIndex:0];
_name.text = html3;
//name 2
NSMutableArray *arr5 = [html1 componentsSeparatedByString:#"<td><font color=#ffffff>"];
if ([arr5 count] > 4) {
NSString *html4 = [arr5 objectAtIndex:5];
NSMutableArray *arr6 = [html4 componentsSeparatedByString:#"</font></td>"];
NSString *html5 = [arr6 objectAtIndex:0];
_name.text = html5;
}
else
{
_name1.text = #"No name";
}
It should be:
if ([arr5 count] > 5) {
NSString *html4 = [arr5 objectAtIndex:5];
...
Indeed, index 5 will correspond to the sixth array item, so you have to have at least 6 objects in it.
Use the same pattern, if you want to check for the array bounds, in all cases.
The problem is that you expect the return from componentsSeparatedByString to return consistent results according to your expectations.
Clearly thats not working.
Array handling is simple. Dont ask for objects that arent there.
Check the count and only access indexes from 0 to count - 1;
If count is zero dont access anything.
I have this array, NSSMutableArray *myarray, which has five objects in it, and I am using a loop like this:
for( className *myObject in myarray)
{
myTextview.text = [NSString stringWithFormat:#"the name is %#", myObject];
}
When I build and run, only the last name shows in my UITextView *myTextview. I logged it, and my loop is working fine -- it's showing all five objects.
The problem seems to be that each time an object is sent to the myTextView, the next object replaces it; is there a way I can hold all of them, so the whole array can be shown?
Each time you pass the loop you are replacing myTextview.text. What you want is to add to the string each time. Try this:
NSMutableString *string = [NSMutableString string];
for( className *myObject in myarray) {
[string appendString:[NSString stringWithFormat:#"the name is %#\n", myObject]];
}
myTextview.text = string;
I am working on a simple comparison of two lists to see which items in an "evaluation" list are contained in a larger "target" list. I am getting the data on-the-fly- by parsing two CSV files and storing everything as strings. I successfully import the data into the data store and I can get a list of entities no problem
The problem comes when I actually do a search. Essentially, I am looking for short ISBNs in the form of 1234 from the evaluation list in the target list, which are in the form of 1234-5. The predicate I am using is I am using the CONTAINS comparison in the form of [NSString stringWithFormat:#"%# CONTAINS %#", kOC_Target_PrintBookCode, evalIsbn]
The error I get is the following (grabbed by my NSLog)
NSInvalidArgumentException: Can't look for value (1494) in string (49885); value is not a string
I get the impression that even though the ISBN is being read from a NSString and the Core Data store has the data point spec'd as a String, that Core Data is still doing something in the background with the value for whatever reason it sees fit. Any ideas?
Here is the relevant process logic (though I use that term dubiously) code. Unless otherwise noted in the code, all values being manipulated and/or stored are NSString:
NSArray *evalBooks = [self getEntitiesByName:kOC_EntityName_EvalBook
usingPredicateValue:[NSString stringWithFormat:#"%# > \"\"", kOC_Eval_Bookcode]
withSubstitutionVariables:nil
inModel:[self managedObjectModel]
andContext:[self managedObjectContext]
sortByAttribute:nil];
if ( ( !evalBooks ) || ( [evalBooks count] == 0 ) ) {
// we have problem
NSLog(#"( !evalBooks ) || ( [evalBooks count] == 0 )");
return;
}
[evalBooks retain];
int firstEvalBook = 0;
int thisEvalBook = firstEvalBook;
int lastEvalBook = [evalBooks count]; NSLog(#"lastEvalBook: %i", lastEvalBook);
for (thisEvalBook = firstEvalBook; thisEvalBook < lastEvalBook; thisEvalBook++) {
NSManagedObject *evalBook = [[evalBooks objectAtIndex:thisEvalBook] retain];
NSString *rawIsbn = [[evalBook valueForKey:kOC_Eval_Bookcode] retain];
NSString *isbnRoot = [[self getIsbnRootFromIsbn:rawIsbn] retain];
// this is a custom method I created and use elsewhere without any issues.
NSArray *foundBooks = [self getEntitiesByName:kOC_EntityName_TargetBook
usingPredicateValue:[NSString stringWithFormat:#"%# CONTAINS %#", kOC_Target_PrintBookCode, isbnRoot]
withSubstitutionVariables:nil
inModel:[self managedObjectModel]
andContext:[self managedObjectContext]
sortByAttribute:kOC_Target_PrintBookCode];
if ( foundBooks != nil ) {
[foundBooks retain];
NSLog(#"foundBooks: %lu", [foundBooks count]);
} else {
}
If you're building your predicate as an NSString, I believe
[NSString stringWithFormat:#"%# CONTAINS %#", kOC_Target_PrintBookCode, isbnRoot]
should actually be
[NSString stringWithFormat:#"%# CONTAINS '%#'", kOC_Target_PrintBookCode, isbnRoot]
It seems that you're confusing the way predicateWithFormat: works with the way stringWithFormat: works.
Presumably either kOC_Target_PrintBookCode or isbnRoot is not an object that can be converted to a string. E.g. if either is an integer, the %# operator cannot convert the integer to a string value.