1

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!

2 Answers 2

2

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 */
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the reply(: somedict is a dictionary with value in my codes. I just add a snippet of the important codes here(: I dont know the "namevalue" of the index array i wanna find as it is according to the user input. That's why i wanna know whether there is a way to retrieve the object index by the"namevalue" (:
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.