8

考虑以下 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];

我能够过滤此数组以查找包含键的字典对象 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);

哪个适当地返回:

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

现在,我想过滤包含NSArray 中任何键的字典对象的数据集。

例如,使用数组:NSArray *keySet = [NSArray arrayWithObjects:@"key1", @"key3", nil];我想创建一个谓词,该谓词返回包含“key1”或“key3”的任何字典对象的数组 (即在此示例中,将返回除第三个对象之外的所有字典对象 - 如它不包含“key1”“key3”)。

关于我将如何实现这一目标的任何想法?我必须使用复合谓词吗?

4

3 回答 3

9

ANY运营商NSPredicate涵盖了这一点:

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

NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"any self.@allKeys in %@", keys];
于 2012-06-20T09:00:11.227 回答
1

做这个:

   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);

非常适合我。希望有帮助

于 2012-06-20T08:58:46.387 回答
1

尽管已经回答了问题,但您还可以使用 block 来获得更多粒度:

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];

可以根据需要重新排列,也许在它自己的方法中。

于 2012-06-20T09:24:06.563 回答