1
votes

I have an NSArray of NSDictionaries.

The dictionaries has keys like this: color, number, code, description and size.

Now I have a key and I want to locate that dictionary inside the array, some magic command like:

NSDictionary *oneDict = [get a dictionary from myArray where "code" is equal to "32"];

code is a key, 32 a value.

I know how to enumerate the array and search one by one every dict, but I know objective-c is a bag full of "tricks" and a "magic command" may exist to extract surgically this dictionary from the array in one line.

Any clues?

3

3 Answers

2
votes

You can use indexOfObjectPassingTest to get the object index:

NSUInteger index = [myArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    NSDictionary* dict = obj;
    return [obj[@"code"] intValue] == 32;
}];

If not found, result will be NSNotFound;

1
votes

This can be done with an NSPredicate simpler:

NSPredicate * predicate = [NSPredicate predicateWithFormat:@"code MATCHES[cd] %@", value];
NSArray *result = [myArray filteredArrayUsingPredicate:predicate];

The result array will hold all NSDictionaries that did match the value. Take a look at the NSPredicate documentation It is very powerful

1
votes

If you intend to do the lookup many times and don't mind spending some time on setup, you could create a dictionary that maps the values of code to the dictionaries that contain those values. i.e.:

NSDictionary * mapping = [ NSDictionary dictionaryWithObjects:myArray forKeys:[ myArray valueForKey:@"code" ] ]
id answer = mapping[@"32" ] ;

This only works if code contains unique values. If the values are not unique:

NSArray * codeValues = [ myArray valueForKey:@"code" ] ;
NSIndexSet indexes = [ codeValues indexesOfObjectsPassingTest:^BOOL(id object){ [ object isEqual:@"32" ] } ] ;
NSArray * matchingDictionaries = [ myArray objectsAtIndexes:indexes ] ;

matchingDictionaries will be an array containing dictionaries where code is @"32".

Replace @"32" in these examples with the value of code you wish to find, &c.