klefevre
klefevre

Reputation: 8735

Filter a NSArray with another NSArray using NSPredicate

I would like to filter an NSArray with another NSArray using NSPredicate

NSArray *a = @[@{@"key1": @"foo", @"key2": @(53), @"key3": @(YES)},
               @{@"key1": @"bar", @"key2": @(12), @"key3": @(YES)},
               @{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];

NSArray *b = @[@{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];

NSArray *expectedResult = @[@{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];

I tried something like :

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"key1 like (key1 IN %@)", b];
NSArray *result = [a filteredArrayUsingPredicate:predicate];

But, unfortunately, I didn't make it work.

Upvotes: 0

Views: 146

Answers (3)

if-else-switch
if-else-switch

Reputation: 977

Use this simple query. For getting the value of key1 from array b you have to use simple KVC valueForKey: method.

NSArray *a = @[@{@"key1": @"foo", @"key2": @(53), @"key3": @(YES)},
               @{@"key1": @"bar", @"key2": @(12), @"key3": @(YES)},
               @{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];

NSArray *b = @[@{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];

NSArray *expectedResult = @[@{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"key1 IN %@",[b valueForKey:@"key1"]];
NSArray *result = [a filteredArrayUsingPredicate:predicate];
NSLog(@"%@",result);

Upvotes: 2

Aditya Mathur
Aditya Mathur

Reputation: 1185

You can do this by NSPredicate class method +predicateWithBlock:

NSArray *a = @[@{@"key1": @"foo", @"key2": @(53), @"key3": @(YES)},
                   @{@"key1": @"bar", @"key2": @(12), @"key3": @(YES)},
                   @{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];  
NSArray *b = @[@{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];   
NSArray *filteredArray = [a filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
        return [b containsObject:evaluatedObject];
    }]];

Upvotes: 0

Hemant Chittora
Hemant Chittora

Reputation: 3162

You can Do this by apply intersection on NSSet

Here is the Example

NSArray *a = @[@{@"key1": @"foo", @"key2": @(53), @"key3": @(YES)},
               @{@"key1": @"bar", @"key2": @(12), @"key3": @(YES)},
               @{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];

NSArray *b = @[@{@"key1": @"foobar", @"key2": @(42), @"key3": @(NO)}];
NSMutableSet *aIntersection = [NSMutableSet setWithArray:a];
[aIntersection intersectSet:[NSSet setWithArray:b]];
NSArray *expectedResult = [aIntersection allObjects];

Upvotes: 1

Related Questions