Reputation: 91
How can I get my object index? I have a dictionary containing arrays and inside the arrays i have multiple dictionary.
My data structure(eg):
Student ------ NSDictionary
Item 0 ------ NSArray<br> Name ----- Grace<br> Age ----- 20<br> Item 1 ------ NSArray<br> Name ----- Anne<br> Age ----- 21<br>
So for example, I have the value of the name, Grace, and I want to get the value of the object index array (in this case, item 0). How can I do so?
I've used the indexOfObject however the results I got back is 2147483647, which i think it means nsnotfound. So i think it doesnt work for this case.
This are my codes:
NSMutableDictionary* namevalue = [[NSMutableDictionary alloc] init];
namevalue = [somedict objectForKey:@"Name"];
int arryindex;
arryindex = [somearray indexOfObject:namevalue];
NSLog(@"Array Index:%i", arryindex);
Can anyone help? Thank you so much!
Upvotes: 1
Views: 6603
Reputation: 7079
If I understood correctly, you're looking for a way to find object index in NSDictionary based on the value of property that object has, right?
E.g. your students
dictionary has a student with name Grace
and you would like to know at which index the student object with name Grace
is stored...
If above is true, here's my (incomplete and rough) solution which works only for objects with NSString
properties, but once you get the idea below, I think you'll be able to modify code to match your needs.
- (NSInteger)indexOfObjectWithPropertyValue:(id)value inDictionary:(NSDictionary *)dict {
NSInteger objectIndex = 0;
unsigned int outCount, i;
for (id key in dict) {
id objForKey = [dict objectForKey:key];
Class lender = [objForKey class];
objc_property_t *properties = class_copyPropertyList(lender, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
id v = [objForKey valueForKey:[NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]];
if ([v isKindOfClass:[value class]] && [v isEqual:value]) {
return objectIndex;
}
}
objectIndex++;
}
return NSNotFound; // i.e. NSIntegerMax
}
and don't forget to include runtime header:
#import <objc/runtime.h>
My code may and probably have some issues:
isEqual:
method which needs to compare properties' values.I hope my "answer" will make it easier for you to implement what you need.
Upvotes: 0
Reputation: 19641
In your code you forgot to include the creation of somedict
and somearray
. The problem may be there.
Also, you don't need to assign namevalue
an empty dictionary and then the actual dictionary inside the array.
Check this fragment of working code:
NSUInteger idx;
NSDictionary *john = [NSDictionary dictionaryWithObjectsAndKeys:@"John", @"name",
[NSNumber numberWithInt:23], @"age", nil];
NSDictionary *jane = [NSDictionary dictionaryWithObjectsAndKeys:@"Jane", @"name",
[NSNumber numberWithInt:24], @"age", nil];
NSArray *students = [NSArray arrayWithObjects:john, jane, nil];
idx = [students indexOfObject:john];
NSLog(@"john is at: %i", idx == NSNotFound ? -1 : idx); /* 0 */
idx = [students indexOfObject:jane];
NSLog(@"jane is at: %i", idx == NSNotFound ? -1 : idx); /* 1 */
Now, try with an object not present in the array:
NSDictionary *mary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mary", @"name",
[NSNumber numberWithInt:22], @"age", nil];
idx = [students indexOfObject:mary];
NSLog(@"mary is at: %i", idx == NSNotFound ? -1 : idx); /* -1 Not found */
And finally with a new object but created as an exact duplicate of an object already present in the array:
NSDictionary *maryjane = [NSDictionary dictionaryWithObjectsAndKeys:@"Jane", @"name",
[NSNumber numberWithInt:24], @"age", nil];
idx = [students indexOfObject:maryjane];
NSLog(@"maryjane is at: %i", idx == NSNotFound ? -1 : idx); /* 1 */
The method indexOfObject
will use isEqual:
to compare objects. You can verify that the new object will be considered as equal to the one inside the array:
NSLog(@"jane is maryjane? %i", [jane isEqual:maryjane]); /* 1 */
Upvotes: 2