5

I have an NSArray full of NSDictionary objects, and each NSDictionary has a unique ID inside. I want to do lookups of particular dictionaries based on the ID, and get all the information for that dictionary in my own dictionary.

myArray contains:

[index 0] myDictionary object
  name = apple,
  weight = 1 pound,
  number = 294,

[index 1] myDictionary object
  name = pear,
  weight = .5 pound,
  number = 149,

[index 3] myDictionary object (etc...)

I want to get the name and weight for the second dictionary object (I won't know the index of the object... if there were only two dicts, I could just make a dictionary from [myArray objectAtIndex:1])

So, say I know the number 149. How would I be able to get the second myDictionary object out of myArray into a new NSDictionary?

geerlingguy
  • 4,682
  • 8
  • 56
  • 92
  • Hmm... possible dupe of http://stackoverflow.com/questions/2457495 and http://stackoverflow.com/questions/958622, but I still don't necessarily like the approaches in those answers (haven't read through in depth yet, though). I currently do three or four queries throughout my app in Core Data, but I'd rather just be able to do everything with one array of dicts. Should I use NSPredicate here? – geerlingguy Feb 17 '11 at 23:17
  • are the `myDictionary` objects actually `NSDictionary` objects or are they custom objects? – Jacob Relkin Feb 17 '11 at 23:32
  • I think @Chuck's answer is correct in this case, I did *not* know that you could use KVC/`NSPredicate` here, but I think I'm wrong. – Jacob Relkin Feb 17 '11 at 23:46

2 Answers2

8

As an alternative to Jacob's answer, you could also just ask the dictionary to find the object:

NSPredicate *finder = [NSPredicate predicateWithFormat:@"number = 149"];
NSDictionary *targetDictionary = [[array filteredArrayUsingPredicate:finder] lastObject];
Chuck
  • 234,037
  • 30
  • 302
  • 389
  • @Chuck Will that really work? I mean, doesn't the field specified in the `NSPredicate` need to correspond to a method on the current object? Since the objects only respond to `-objectForKey:`, not `-number`, I don't think it'd work, but then again I could be wrong... – Jacob Relkin Feb 17 '11 at 23:29
  • Will try this... I like the idea of doing it this way, since I'm going to have to do this in a few different places, and I hate loops (when I can avoid them). – geerlingguy Feb 17 '11 at 23:31
  • @Jacob Relkin: I could be wrong too. I thought NSPredicate used KVC, which works with NSDictionaries and objects. But I can't test the code at the moment. – Chuck Feb 17 '11 at 23:41
  • @Chuck Oh you mean it'd invoke `valueForKey:` on the `NSDictionary`? Hmm, maybe it actually *would* work... +1 to you! – Jacob Relkin Feb 17 '11 at 23:42
  • @Chuck Nice. I will remember this for future reference! Thank you! – Jacob Relkin Feb 18 '11 at 00:19
3

You'd need to iterate through every NSDictionary object in your NSArray:

- (NSDictionary *) findDictByNumber:(NSInteger) num {
   for(NSDictionary *dict in myArray) {
     if([[dict objectForKey:@"number"] intValue] == num) 
        return [NSDictionary dictionaryWithObjectsAndKeys:[dict objectForKey:@"weight"], @"weight", [dict objectForKey:@"name"], @"name", nil];
   }
   return nil;
}
Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
  • 1
    This wouldn't be too bad, I was hoping to avoid having to do that, though, as I thought this kind of thing would be easier to do (it seems like a pretty common pattern to me...). Well, maybe easier's not the right word - less code, maybe? – geerlingguy Feb 17 '11 at 23:30
  • I'm going to try Chuck's method first (in a little bit), and see if it works. – geerlingguy Feb 17 '11 at 23:33