How to test if there is an _NSCFConstantString in an NSMutableArray? - ios

Alright, so I have a Popover, containing a tableView, that is populated by an NSMutableArray filled with strings. But there is always one blank/empty string in my NSMutableArray and in turn always an empty cell in my popover table. I've single stepped my project and found that the empty string is a string constant(_NSCFConstantString).
I've tried to get rid of the empty string occurrence by doing a simple empty string test:
[str isEqualToString:#""]
But this doesn't work, I'm assuming because the empty string in my array is of type _NSCFConstantString...?
So what I'm wondering is if there is a way to test if an object is of type _NSCFConstantString, or if you guys have a better way to test if a string is empty...
Here is my full code that pertains to my issue:
NSString *str;
for (int i = 0; i < [self.flattenedDocList count]; i++) {
str = [self.flattenedDocList objectAtIndex:i];
if(![str isKindOfClass:[NSString class]]){
[self.flattenedDocList removeObject: str];
NSLog(#"Just Deleted:%#",str);
}else if([str isEqualToString:#""]){
[self.flattenedDocList removeObject: str];
NSLog(#"Just Deleted:%#",str);
}
}
The first if-statement is a check to get rid of any NSNull objects in my array. Unfortunately this doesn't get rid of the string constants :/
Thank you, any help is greatly appreciated.

Alright, so I made the rookie mistake of modifying an NSMutableArray while enumerating. Also, H2CO3 was right, _NSCFConstantString IS a concrete subclass of NSString, so we can use all NSString methods on them.
Here is a good way to modify an NSMutableArray while enumerating it.
NSMutableArray *tempArray = [[NSMutableArray alloc] initWithArray:self.docList];
self.listForThePopover = [[NSMutableArray alloc] init];
NSString *str;
for (int i = 0; i < [tempArray count]; i++) {
str = [tempArray objectAtIndex:i];
//NSLog(#"~str:%#~",str);
//check if the str is of the NSString class AND if it's NOT empty
if(([str isKindOfClass:[NSString class]]) && (![str isEqualToString:#""])){
//add the string to the list that we want to actually use.
[self.listForThePopover addObject:str];
//NSLog(#"Just Added:%#",str);
}
}

But this does not work, I'm assuming because the empty string in my array is of type _NSCFConstantString...?
Not quite. _NSCFConstantString is a concrete subclass of NSString, so it should work.
Maybe the string is not really and empty string, or it isn't in the array. Check if it's a space (or more of them), by accident. Examine its length property, etc.
By the way, it's a very bad idea to modify a mutable collection while enumerating it, it can lead to logic errors. Maybe that's also part of your current problem in this case.

Related

iOS NSDictionary Values

I have an array of NSDictionaries and i can access the values in them just fine but i am trying to filter these dictionaries down based on a user's search (user can only search by the dictionary key (#"uniqueSignName").
Once the user has searched through the names property i then need to display ALL dictionary associated data for that #"uniqueSignName" value.
I do the following code and always get the correct amount of NSLogs. For the life of me i cannot remember how to GET those dictionaries.
for (int i = 0; i < [filteredDictionaries count]; i++) {
if ([[[filteredDictionaries valueForKey:#"uniqueSignName"] objectAtIndex:i] isEqualToString:[self.filteredResults objectAtIndex:indexPath.row]]) {
NSLog(#"Power Rangers");
}
}
Eg: I search for "John"
NSLog: #"Power Rangers"
Correctly only appears once.
Now, how do i access another property of "John's" dictionary?
If you want to search the name then better way is that to use NPredicate without iterating the array.
Please see the below example..it may help you...
// Here array is your main array...
NSArray *filteredarray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(uniqueSignName == %#)", #"John"]];
So the problem is solved, I can now access all the filtered properties.
for (NSDictionary *dict in filteredDictionaries) {
if ([[self.filteredResults objectAtIndex:indexPath.row] isEqualToString: dict[#"uniqueSignName"]]) {
NSString *myString = [NSString stringWithFormat:#"%#", dict[#"pType"]];
NSLog(#"hugh: %#", myString);
myString = displayPtype;
}
}

How to look for a specific value in .plist and then retrieve matches

As the title suggests, my .plist file is in this format - I don't know how to mark it up well for you to read. Stackoverflow doesn't understand the format.
root (array)
Item 0 - Dict
numberOfPerson String
recipeName String
recipeIngredients String
Item 1 -Dict
NumberOfPerson String
...
I have a textfield for user and user will enter a couple of strings.
I want to look for matches with input and recipeIngredients of each item.
And when it is found I want to go to that cell in my tableview which i implemented.
how can I accomplish this.
These are what I have tried so far
NSString *path = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
NSArray *arrayOfPlist = [[NSArray alloc] initWithContentsOfFile:path];
This turned out useless I can not use objectForKey
for (int i=0; i<2; i++) {
recipeIngredientsArray = [[arrayOfPlist objectAtIndex:i] objectForKey:#"recipeIngredients"];
}
This didn't help me either I can not maintain a good isequl method
Thanks for the help.
You have an array of dictionaries that you want to filter. Look at using indexesOfObjectsPassingTest:. Run this on the array and test the passed dictionary to check the value of the recipeIngredients value.
NSIndexSet *indexes = [arrayOfPlist indexesOfObjectsPassingTest:^BOOL (NSDictionary *obj, NSUInteger idx, BOOL *stop) {
return [obj[#"recipeIngredients"] rangeOfString:input options:NSCaseInsensitiveSearch].location != NSNotFound;
}];
Then you can use indexes to see if you have any matches and to display them. Or, you could just use filteredArrayUsingPredicate: to filter the array directly:
NSArray *results = [arrayOfPlist filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"recipeIngredients CONTAINS[cd] %#", input]];
and then show only the filtered results in the table view.

How to check if a NSArray has the values of another array

I have my array unique that is my main array and my array kind. I need to check that only 1 value of kind is present in the array unique. Then if there is more than 1 value of the array kind in unique I need to unset all values but the first one used in the array.
The further i got to achieve this is with the following code but I can not store the indexpath of the found object to do a later comparison. xcode says "bad receiver type nsinteger"
could anyone help me to achieve this?
kind = #[#"#Routine",#"#Exercise",#"#Username"];
NSMutableArray *uniqueKind = [NSMutableArray array];
for (NSString* obj in kind) {
if ( [unique containsObject:obj] ) {
NSInteger i = [unique indexOfObject:obj];
[uniqueKind addObject: [i intValue]];
}
}
An NSInteger is like an int, so you can't send it a message ([i intValue]). Also, you can't add an NSInteger to an array without making it an NSNumber or some other object type. You can do it like this:
NSInteger i = [unique indexOfObject:obj];
[uniqueKind addObject: [NSNumber numberWithInteger:i]];
Also (without understanding what you're doing) you might want to use an NSSet instead of an array. And you can combine a couple of calls:
NSUInteger i = [unique indexOfObject:obj];
if ( i != NSNotFound ) {
[uniqueKind addObject:[NSNumber numberWithInteger:i]];
}
I'm not sure if it would solve your problem, but have you considered using sets (or mutable variation) instead of arrays? They ensure uniqueness and they allow you to check for intersection/containment. See the NSSet class reference.
You have to add objects to the NSMutableArray, not the actual intValue. Try converting teh integer to a NSNumber first.
[uniqueKind addObject: [NSNumber numberWithInt:i]];
instead.
(edited )

How to create a NSArray of two valueForKey elements of an object from another array

I would like to create an NSArray of NSStrings that is a concatinated value of two elements from a NSDictionary found in my original NSArray. A bit complicated I know but I feel I am almost halfway there and will describe where I am up too.
So I have a NSArray of NSDictionaries, the NSDictionaries look like this -
NAME
NICK NAME
YEAR
LEGAL
I would like to take the Name and Nick name values of each dictionary and form them into an NSArray of NSStrings that look like this
Name (Nick Name)
but I am at abit of a loss on how to do this properly I have gotten as far as a For loop lol
for (int i = [dataArrayOfDictionaries count]; i <= [dataArrayOfDictionaries count]; i++) {
}
My main questions are, how do I access these Name and Nick Name element of each NSDictionary object of the array.
Then how do I put them into a formatted string like the example above and put them into their own NSArray
any help would be greatly appreciated.
So if I understand correctly, you want to grab the name and nick name from each dictionary that you have stored in an array and then combine the two and put them in a new array? Try something like this:
NSMutableArray *yourNewMutableArray = [[NSMutableArray alloc]init];
for(NSDictionary *dict in dataArrayOfDictionaries)
{
NSString *realName = [dict objectForKey:#"NAME"];
NSString *nickName = [dict objectForKey:#"NICK NAME"];
NSString *combined = [[[realName stringByAppendingString:#" ("]stringByAppendingString:nickName]stringByAppendingString:#")"];
[yourNewMutableArray addObject:combined];
}

Dynamica string count in NSMutableArray in NSMutableDictionary

I am familiar with getting a string count from a known array
int numberOfWords = [self.wordArray count];
but I have an unknown number of strings in an unknown number of arrays, all referenced by a dictionary. This works - good.
NSMutableDictionary *eqClasses = [[NSMutableDictionary alloc] init];
The arrays and strings are added at runtime (with help of this board):
NSMutableArray* array = [eqClasses objectForKey:wordPattern];
if(!array) {
// create new array and add to dictionary if wordPattern not found
array = [NSMutableArray array];
[eqClasses setObject:array forKey:wordPattern];
}
[array addObject:tempWordStr];
Now I need to iterate through the dictionary and get the array with the largest word count. Is there a way to scroll through all the arrays in the dictionary without using a key (I won't know all the word patterns as they are generated dynamically), AND once I find the array with the most words, get that array/value and key/wordpattern?
Well, there is a way to get all the keys within a dictionary:
NSArray *keyArray = [myDict allKeys];
And then you just go through the array and get the object for each key.
A fast enumeration should work nicely.
for (NSString *string in NSArray){
...
} //Assuming your keys are strings!
You can save each string to a temporary string, and when encountering a new string, compare to find the longer one. If it's longer, replace the old string with the longer one.
Hope this helped! ^_^
^_^
Okay, so now that you have an array full of all the keys in the dictionary,
you can iterate through the entire array and get the corresponding value (the string) for each key.
NSArray *keyArray = [myDict allKeys]; //This gets all the keys
NSString *tempString = #""; //This is the string you will save the longest string in. It gets updated when a longer string is found in the following loop.
for (NSString *string in keyArray){
NSString *stringFromCurrentKey = [myDict objectForKey:string];
if(stringFromCurrentKey.length > tempString.length){
tempString = stringFromCurrentKey;
}
} //By the end, you should be left with the longest string contained in tempString!
^_^ Hope this made sense and helped!
Try this code:
NSArray *largestArray = nil;
for (NSString *key in dictionary)
{
NSArray *array = [dictionary objectForKey:key];
if (array.count > largestArray.count) // largestArray.count is 0 if largestArray is nil
{
largestArray = array;
}
}

Resources