Grace
Grace

Reputation: 91

How to get object index?

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

Answers (2)

matm
matm

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:

  • the most obvious isEqual: method which needs to compare properties' values.
  • above code does not cover a situation when there are many objects with same value (like many students with the same name!)
  • ???

I hope my "answer" will make it easier for you to implement what you need.

Upvotes: 0

djromero
djromero

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

Related Questions