I have an array which consists of several NSDictionaries with the keys:
NSString *nameNSString *IDNSDictionary *phoneNumbersDictNow I want to filter this array to find the one which has the phoneNumbersDict key @"keyIAmLookingFor" and the value @"valueIAmLookingFor".
NSMutableArray *addressBookPhoneIndividuals = [NSMutableArray array];
for (int i = 0; i < x; i++) {
    [addressBookPhoneIndividuals addObject:@{
        @"name" : @"...",
        @"ID" : @"...",
        @"phoneNumbers" : @{...}
    }];
}
NSString *keyIAmLookingFor = @"work";
NSString *valueIAmLookingFor = @"444-567-9019";
NSArray *addressBookPhoneIndividuals = @[
    @{
        @"name" : @"Mike Rowe",
        @"ID" : @"134",
        @"phoneNumbers" : @{
            @"work" : @"123-456-8000",
            @"school" : @"647-5543",
            @"home" : @"123-544-3321",
        }
    },
    @{
        @"name" : @"Eric Johnson",
        @"ID" : @"1867",
        @"phoneNumbers" : @{
            @"work" : @"444-567-9019",
            @"other" : @"143-555-6655",
        }
    },
    @{
        @"name" : @"Robot Nixon",
        @"ID" : @"-12",
        @"phoneNumbers" : @{
            @"work" : @"123-544-3321",
            @"school" : @"123-456-8000",
            @"home" : @"444-567-9019",
        }
    },
];
NSString *keyPath = [@"phoneNumbers." stringByAppendingString:keyIAmLookingFor];
NSPredicate *predicate =
[NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:keyPath]
                                   rightExpression:[NSExpression expressionForConstantValue:valueIAmLookingFor]
                                          modifier:NSDirectPredicateModifier
                                              type:NSEqualToPredicateOperatorType
                                           options:0];
NSArray *result = [addressBookPhoneIndividuals filteredArrayUsingPredicate:predicate];
This will return an array containing the "Eric Johnson" dictionary.
I like to recommend NSComparisonPredicate when doing any kind of complex matching. Look at the options for modifier, type and options. There are some good built in matching engines in there - including regular expressions and case insensitivity. Anyway, it probably isn't necessary here, so you could substitute the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", keyPath, valueIAmLookingFor];
If you only care about the first result, you can skip the keyPath/predicate business altogether:
for (NSDictionary *individualDict in addressBookPhoneIndividuals) {
    NSDictionary *phoneNumbers = [individualDict objectForKey:@"phoneNumbers"];
    NSString *possibleMatch = [phoneNumbers objectForKey:keyIAmLookingFor];
    if ([possibleMatch isEqualToString:valueIAmLookingFor]) {
        return individualDict;
    }
}
return nil;
You could use an NSPredicate to filter your array. Something like the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"phoneNumbers.keyIAmLookingFor == %@", @"valueIAmLookingFor"];
NSArray *matches = [addressBookPhoneIndividuals filteredArrayUsingPredicate:predicate];
I don't quite get how you want to filter your array, but one simple approach I use often is block-based filtering:
NSIndexSet* filteredIndexes = [addressBookPhoneIndividuals indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
    NSString *name = [obj objectForKey:@"name"];
    NSString *ID = [obj objectForKey:@"ID"];
    NSDictionary *phoneNumbersDict = [obj objectForKey:@"phoneNumbersDict"];
    return [[phoneNumbersDict objectForKey:@"keyIAmLookingFor"] isEqualToString:@"valueIAmLookingFor"];
}];
NSArray* filteredArray = [addressBookPhoneIndividuals objectsAtIndexes:filteredIndexes];
Does this help?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With