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 complex matching. See options for modifier, type, and parameters. There are good engines built into them, including regular expressions and case insensitivity. In any case, this is probably not necessary here, so you can replace the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", keyPath, valueIAmLookingFor];
If you only care about the first result, you can generally skip the keyPath / predicate business:
for (NSDictionary *individualDict in addressBookPhoneIndividuals) { NSDictionary *phoneNumbers = [individualDict objectForKey:@"phoneNumbers"]; NSString *possibleMatch = [phoneNumbers objectForKey:keyIAmLookingFor]; if ([possibleMatch isEqualToString:valueIAmLookingFor]) { return individualDict; } } return nil;
Sterling archer
source share