This question already has answers here:
Finding a substring in a NSString object
(7 answers)
NSString search whole text for another string
(3 answers)
Closed 9 years ago.
I am performing a method call that places any objects found in the background into an NSArray object called "objects".
When I NSLog the counts property of "objects" it tells me that the array contains 1 object which is correct.
When I NSLog the NSArray object called "objects" it prints out the following:
(
"<PFUser:nzyjeVFgjU:(null)> {\n email = \"hahshshs#aol.com\";\n username = hzhjsshhsppppp;\n verificationCode = 6449;\n}"
)
Here is my problem. I need to create an if statement that takes another value I already have and compares it to the 4 digit number that verificationCode is equal to eg. Above in the code it says "verificationCode = 6449"
I am basically trying to compare a 4 digit code that I already have to the verificationCode that is contained in this single NSArray object.
I know how to write if statements, but i have no idea how to specifically focus on "verificationCode = 6449" since it is just text inside of a string.
I have been trying to figure out a way to do this for an hour now so any help is greatly appreciated thank you.
Just found the answer here: https://stackoverflow.com/a/7574136/3117509
I tried searching earlier but was searching for "search array for string" when I should have been searching for something like "search for string within a string" or "search for text within a string."
If I understand your question correctly, you're trying to iterate through an array and find if a string is there? Don't have access to a Mac right now, so I'm not sure if this will compile.
NSArray* someArray = [[NSArray alloc] initWithObjects:#"test", #"test1", #"test2", nil];
for(int i = 0; i < (int)[someArray count]; i++) {
if([[someArray objectAtIndex:i] isEqualToString #"test"]) {
//match found. handle the match
}
}
Related
This question already has answers here:
XCTAssertEqual fails to compare two string values?
(3 answers)
Closed 2 years ago.
I'm trying to implement a unit test(XCTest) to compare two NSArray objects:
Here is my implementation:
- (void)testTwoNumsArrays {
NSArray *result = #[#20,#20];
NSArray *expecteResult = #[#20,#20];
XCTAssertEqual(result, expecteResult);
}
I'm getting this error:
((result) equal to (expecteResult)) failed: ("{length = 8, bytes = 0xb0cfc00001000000}") is not equal to ("{length = 8, bytes = 0x9032ce0001000000}")
Any of you know why I can not compare the two arrays. In Swift it works just fine.
I'll really appreciate your help.
The problem is you are comparing the pointers to the objects and not the objects themselves.
XCTAssertEqual is essentially doing a check like the following, which is only comparing the pointer values.
if (a != b) assert();
You want something more along the lines of
if (![a isEqual:b]) assert();
This can be achieved with the XCTAssertEqualObjects call.
More information:
XCTAssertEqual fails to compare two string values?
https://developer.apple.com/documentation/xctest/xctassertequalobjects
This question already has answers here:
NSMutableArray addObject not working
(2 answers)
Closed 7 years ago.
I have created a function within my code that converts whatever is in the textfield of my app to append to my array. However, when I set a breakpoint in the code, it returns that my array, _descriptionArray is nil. Why is that?
I want whatever value is in the descriptionTextField.text to append to my _descriptionArray.
Thanks for the help!
-(NSMutableArray *)descriptionConversion{
[_descriptionArray addObject: (descriptionTextField.text)];
return _descriptionArray;
}
Did you ever initialize _descriptionArray? If not, be sure to initialize the array with _descriptionArray = [NSMutableArray array];. If you don't initialize the array, it will be nil. You can only add an object to an array; not to nil.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
This is for Xcode 5 and for iOS apps; I'm working with Objective-C code.
Okay so for example, if I put into the first text field "I was born in 1995." and when I click a convert button, I want it to say "I was conceived circa 1995." How can I go about doing that? The problem I'm having is being able to replace a word with another word.
Like, how do I return whats in the text field to be replace the possible words into whatever the person types in? Sort of like a translator app, the way it replaced words.
My question concerns that if the user were to type anything into the text field, then it would rephrase it for him with words that have synonyms to be other words.
Yes, it is about replacing substrings, but it will replace whatever the user types into it.
I understand that stringByReplacingOccurrencesOfString:withString: makes sense, but what would go after that to apply to whatever the user typed in?
Basically, let's say a translator app. If I type in: "I am very smart." it would rephrase to: "I am very intellectual." It has to deal with whatever the user types in.
If the string is in NSString, you can use the stringByReplacingOccurrencesOfString:withString: method.
NSString *str = #"I was born in 1995.";
str = [str stringByReplacingOccurrencesOfString:#"born in" withString:#"conceived circa"];
Not sure though if this is what you mean.
Given a word, you want to find words with similar meaning. You will need a lot of data - arrays of words grouped by meaning. A given word may appear in several of these arrays depending on context (one reason why machine interpretation of language is difficult...).
The easy way to separate the string into words is to use componentsSeparatedByString: with a string of #" ". After that you need to identify which strings you want to try and replace. Whether or not they return anything useful using the dictionary described below is one way to decide.
A specific word can be used as a key into a dictionary returning an array of arrays. Let's say the word is "iron". When you use that as a key in your master dictionary it returns an array containing three arrays. In one are all the words (as NSStrings) that mean "elemental iron", in another are all the words that mean "smooth clothes with a hot tool" such as "press" or "smooth", in another are tool-like uses such as "shooting iron", "branding iron" etc.
The hardest thing you have to do is identify the context and choose the right array, or else you end up generating nonsense.
Once you have identified context you can choose any other word from the selected array, substitute it in the sentence, and then process other words you want to substitute.
To separate a string such as
NSString *string = #"I am very smart."
you would use
NSArray *words = [string componentsSeparatedByString:#" "];
you can iterate over the words with
for(NSString *word in words) {
// do something with NSString *word here
}
Here's a quick look at building the master dictionary - it hasn't been run but I'm sure someone will spot if there's a mistake...
// NSArray *arrayOfArraysOfSimilarWords; <- populated elsewhere, as shown below
// array
// |
// - "cat", "feline", "pussycat", "gato"
// - "shoe", "pump", "clog", "trainer"
NSMutableDictionary *masterDictionary = [NSMutableDictionary dictionary];
for(NSArray *wordArray in arrayOfArraysOfSimilarWords) {
for(NSString *word in wordArray) {
NSArray *arrayOfWordArrays = masterDictionary[word];
if(arrayOfWordArrays == nil) {
masterDictionary[word] = #[wordArray];
} else {
// entry exists
NSSet *wordArraySet = [NSSet setWithArray:arrayOfWordArrays];
if([wordArraySet containsObject:wordArray]) {
// this word array is already returned as a result for this word
continue;
}
// there is no entry for this word array yet - add an array containing the current word array
NSMutableArray *newArrayOfWordArrays = [NSMutableArray arrayWithArray:arrayOfWordArrays];
[newArrayOfWordArrays addObject:wordArray];
masterDictionary[word] = newArrayOfWordArrays;
}
}
}
If you're trying to do in place replacement of strings while the user types you will need probably to use the UITextFieldDelegate method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
This is called on every character insertion (or text paste) in a UITextField.
Pseudo code (because I'm writing this off the top of my head):
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSMutableString *proposedText = [textField.text mutableCopy];
[proposedText replaceCharactersInRange:range withString:string];
if (proposedText contains word I want to replace)
{
replace word in proposedText
textField.text = proposedText;
textField.selectedTextRange = new selection
return NO;
}
return YES;
}
Hope this helps.
This question already has answers here:
Getting a random object from NSArray without duplication
(3 answers)
Closed 7 years ago.
I have an array of random properties I would like to assign to equipment within the game I'm developing.
The code that I use below is returning an NSArray. I'm interested if there's way to get item indices from that array without getting duplicate values. The obvious solution is to create a mutable array with the returned array, do random, remove item that was returned and loop until the number of items is received.
But is there a different way of getting X random items from NSArray without getting duplicates?
//get possible enchantments
NSPredicate *p = [NSPredicate predicateWithFormat:#"type = %i AND grade >= %i", kEnchantmentArmor,armor.grade];
NSArray* possibleEnchantments = [[EquipmentGenerator allEnchantmentDictionary] objectForKey:#"enchantments"];
//get only applicable enchantments
NSArray *validEnchantments = [possibleEnchantments filteredArrayUsingPredicate:p];
NSMutableArray* mutableArray = [NSMutableArray arrayWithArray:validEnchantments];
NSDictionary* enchantment = nil;
if(mutableArray.count>0)
{
//got enchantments, assign number and intensity based on grade
for (int i = 0; i<3;i++)
{
enchantment = mutableArray[arc4random()%mutableArray.count];
[mutableArray removeObject:enchantment];
//create enchantment from dictionary and assign to item.
}
}
You can shuffle the array using one of the following techniques:
What's the Best Way to Shuffle an NSMutableArray?
Non repeating random numbers
Then, take the first X elements from the array.
Many years ago, I was working on card game and I realized that shuffling the deck was an inefficient way to get random cards. What I would do in your shoes is pick a random element, and then replace it with the element at the end of the array, like so:
#interface NSMutableArray (pickAndShrink)
- (id) pullElementFromIndex:(int) index // pass in your random value here
{
id pickedItem = [self elementAtIndex:index];
[self replaceObjectAtIndex:index withObject:[self lastObject]];
[self removeLastObject];
return pickedItem;
}
#end
The array will shrink by one every time you pull an element this way.
You could use a random number generator to pick a starting index, and then pick the subsequent indices based on some kind of math function. You would still need to loop depending on how many properties you want.
Eg:
-(NSMutableArray*)getRandomPropertiesFromArray:(NSArray*)myArray
{
int lengthOfMyArray = myArray.count;
int startingIndex = arc4random()%lengthOfMyArray;
NSMutableArray *finalArray = [[NSMutableArray alloc]init]autorelease];
for(int i=0; i<numberOfPropertiesRequired; i++)
{
int index = [self computeIndex:i usingStartingIndex:startingIndex origninalArray:myArray];
[finalArray addObject:[myArray objectAtIndex:index]];
}
return finalArray;
}
-(int)computeIndex:(int)index usingStartingIndex:(int)startingIndex
{
//You write your custom function here. This is just an example.
//You will have to write some code to make use you don't pick an Index greater than the length of your array.
int computedIndex = startingIndex + index*2;
return startingIndex;
}
EDIT: Even your computeIndex function could use randomness in picking the subsequent indices. Since you have a startingIndex, and another index, you could use that to offset your function so that you never pick a duplicate.
EDIT: If your array is very large, and the subset you need to pick is small, then rather than shuffle the entire array (maybe more expensive), you could use this method to pick the number of items you need. But if your array is small, or if the number of items you need to pick are almost the size of the array, then the godel9's solution is better.
You can use a mutable array and then remove them as the are selected, use something like random()%array.count to get a random index. If you don't want to modify the array then copy it with [array mutableCopy].
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
My model is intended to store JSON data. Part of what's to be stored is an array nested in the JSON, which could be a varying number of elements. This is how I retrieve that data in code.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"SomeJsonFile" ofType:#"json"];
NSData *jsonFromFile = [[NSData alloc] initWithContentsOfFile:filePath];
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:jsonFromFile options:0 error:&error];
DLog(#"simulated 'Stuff' JSON, stored in dictionary: %#", jsonData);
That works great. A callback sends along that dictionary, at which point I experience my problem. Here's an example of the nested array in the JSON.
stuff = (
{
id = 11;
"someState" = 1;
someNumber = 100;
description = "Human-readable text for thing #11!";
},
{
id = 22;
"someState" = 0;
someNumber = 20;
description = "Human-readable text for thing #22!";
},
{
id = 33;
"someState" = 1;
someNumber = 250;
description = "Human-readable text for thing #33!";
},
);
My model should store the data sent along there, but since that nested array is an unknown amount of elements, I've elected to:
Use an NSMutableArray to store the IDs of each array element.
Use an NSMutableDictionary for each property of the element (like someState, someNumber, description).
When the time comes to list all the elements of the model, I'll iterate through the array of IDs and use each ID as a key for each of the NSMutableDictionary properties, thus retrieving everything I need.
Those NSMutableDictionary properties from step 2 aren't responding. They don't set the keys or values; they remain null. From other questions, it seems this is because they aren't initialized. Also from other questions, I've been able to add and remove keys/values to an arbitrary NSMutableDictionary that I initialized (not a part of the model).
The controller should be blind to this initialization pertinent to the model, but I can't seem to initialize the NSMutableDictionary properties by overriding the getters/setters of the model. What is the correct way in objective-C to set up my model with NSMutableDictionary properties such that I can set keys and values in it from my controller?
I also feel like my many-dictionaries indexed by ids in an array solution is overkill. If you can spot that and know the better way to deal with this in iOS, please feel free to lend your wisdom.
EDIT
At the request of Marcus Adams, here is the code where I use the NSMutableDictionary properties. I do not initialize the NSMutableDictionary properties; where to do that so that it's appropriate to the MVC model is my question. His answer has led me to try initializing by overriding "init", and this works as part of the instantiation of the model (Marcus Adams will be marked as the answer if he provides the explanation, since he led me to the answer, but answers with code samples for correctly overriding "init" will be up voted).
// Now we're ready to store what's in the JSON.
NSDictionary *stuff = jsonData[#"stuff"];
NSMutableDictionary *tempDictBecauseAllocNeeded = [[NSMutableDictionary alloc] init];
for (NSDictionary *thing in stuff) {
[tempDictBecauseAllocNeeded setObject:thing[#"description"] forKey:thing[#"id"]]; // This works!
theModel.thingDescriptions[thing[#"id"]] = thing[#"description"]; // This wasn't working!
[theModel.thingIds addObject:thing[#"id"]]; // This is the array of ids used to retrieve values from each dictionary
}
I guess your code should be working now. I was curious how you were copying the NSDictionaries and thought the problem might be there. Obviously, you discovered that you hadn't initialized tempDictBecauseAllocNeeded. I wouldn't use a getter to initialize unless you are keeping tempDictBecauseAllocNeeded around for awhile. If you are, storing it as a property and initializing it in a getter is the simplest thing to do.
// Getter ensures that when you reference self.tempDictBecauseAllocNeeded
/// it's always initialized
-(NSMutableDictionary *) tempDictBecauseAllocNeeded {
if (!_tempDictBecauseAllocNeeded) {
_tempDictBecauseAllocNeeded = [[NSMutableDictionary alloc] init];
}
return _tempDictBecauseAllocNeeded;
}
Since the original JSON parsing, by default, creates mutable leaves, even though you assign it to an NSDictionary, each leaf in there is still mutable.
So, when you (shallow copy) over the leaves to your NSMutableDictionary, they are still mutable, of course.
stuff = ( ...
This is not a JSON array, is it supposed to be? JSON array would be
stuff = [ ...