我有一组“白名单”键,我想根据这些键过滤NSDictionary;
NSArray *whiteList = @["one", "two"];
NSDictionary *dictionary = @{
@"one" : @"yes",
@"two" : @"yes",
@"three" : @"no"
};
NSDictionary *whiteDictionary = [dictionary dictionaryWithValuesForKeys:whiteList];
产生:
{
one = "yes";
two = "yes;
}
但是,如果我的字典不包含一个或多个键:
NSArray *whiteList = @["one", "two"];
NSDictionary *dictionary = @{
@"one" : @"yes"
};
NSDictionary *whiteDictionary = [dictionary dictionaryWithValuesForKeys:whiteList];
我回来了:
{
one = "yes";
two = "<null>";
}
有没有办法根据一组键过滤字典而不会获得不存在的键。
答案 0 :(得分:4)
更新
您可以通过过滤原始字典的所有密钥,然后从过滤的密钥列表构建白名单字典来获得功能解决方案:
NSDictionary *whiteDictionary = [dictionary dictionaryWithValuesForKeys:[dictionary.allKeys filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self IN %@", whiteList]]];,
或两行,通过为谓词声明一个单独的变量,来减小行的大小:
NSPredicate *whitelistPredicate = [NSPredicate predicateWithFormat:@"self IN %@", whiteList];
NSDictionary *whiteDictionary = [dictionary dictionaryWithValuesForKeys:[dictionary.allKeys filteredArrayUsingPredicate:whitelistPredicate]];,
原始回答
半功能方法看起来像这样:
NSDictionary *whiteDictionary = [dictionary dictionaryWithValuesForKeys:whiteList];
whiteDictionary = [whiteDictionary dictionaryWithValuesForKeys:[whiteDictionary keysOfEntriesPassingTest:^(NSString *key, id obj, BOOL *stop) { return obj != [NSNull null]; }]];
或者,您可以通过字典枚举并构建过滤后的字典:
NSMutableDictionary *whiteDictionary = [NSMutableDictionary dictionary];
[dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
if ([whiteList containsObject:key]) {
whiteDictionary[key] = obj;
}
}
答案 1 :(得分:1)
如果您不关心在字典中对集合进行递归操作,那么这样的事情应该有效:
- (NSDictionary *)dictionaryWithNonNullValuesForKeys:(NSArray *)keys {
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
for (id key in keys) {
id value = self[key];
if ([value isKindOfClass:[NSNull class]]) {
NSLog(@"Warning, value for key was null, skipping key %@", key);
}
else {
mutableDictionary[key] = value;
}
}
return [mutableDictionary copy];
}