NSPredicate 'OR' filtering based on an NSArray of keys

谁都会走 提交于 2019-12-09 10:26:57

问题


Consider the following NSArray:

NSArray *dataSet = [[NSArray alloc] initWithObjects:
                 [NSDictionary dictionaryWithObjectsAndKeys:@"abc", @"key1", @"def", @"key2", @"hij", @"key3", nil], 
                 [NSDictionary dictionaryWithObjectsAndKeys:@"klm", @"key1", @"nop", @"key2", nil], 
                 [NSDictionary dictionaryWithObjectsAndKeys:@"qrs", @"key2", @"tuv", @"key4", nil], 
                 [NSDictionary dictionaryWithObjectsAndKeys:@"wxy", @"key3", nil], 
                 nil];

I am able to filter this array to find dictionary objects that contain the key key1

// Filter our dataSet to only contain dictionary objects with a key of 'key1'
NSString *key = @"key1";
NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"%@ IN self.@allKeys", key];
NSArray *filteretSet1 = [dataSet filteredArrayUsingPredicate:key1Predicate];
NSLog(@"filteretSet1: %@",filteretSet1);

Which appropriately returns:

filteretSet1: (
        {
        key1 = abc;
        key2 = def;
        key3 = hij;
    },
        {
        key1 = klm;
        key2 = nop;
    }
)

Now, I am wanting to filter the dataSet for dictionary objects containing ANY of the keys in an NSArray.

For example, using the array: NSArray *keySet = [NSArray arrayWithObjects:@"key1", @"key3", nil]; I want to create a predicate that returns and array of any dictionary objects that contain either 'key1' or 'key3' (ie. in this example all dictionary objects would be returned except for the third object - as it does not contain either 'key1' or 'key3').

Any ideas on how I would achieve this? Would I have to use a compound predicate?


回答1:


The ANY operator of NSPredicate covers this:

NSSet *keys = [NSSet setWithObjects:@"key1", @"key3", nil];

NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"any self.@allKeys in %@", keys];



回答2:


Do this:

   NSString *key = @"key1";
   NSString *key1 = @"key3";
   NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"%@ IN self.@allKeys OR %@ IN self.@allKeys",key,key1];
   NSArray *filteretSet1 = [dataSet filteredArrayUsingPredicate:key1Predicate];
   NSLog(@"filteretSet1: %@",filteretSet1);

Works perfectly for me. Hope Helpful




回答3:


Altough the question has been answered, you could also use block for more granularity:

NSArray *filter = [NSArray arrayWithObjects:@"key1", @"key3",nil];

NSPredicate *filterBlock = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind){        
    NSDictionary *data = (NSDictionary*)obj;

    // use 'filter' and implement your logic and return YES or NO
}];

[dataSet filteredArrayUsingPredicate:filterBlock];

That could be rearranged as you want, maybe within its own method.



来源:https://stackoverflow.com/questions/11115377/nspredicate-or-filtering-based-on-an-nsarray-of-keys

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!