如何过滤含多层NSDictionary的NSArray?求NSPredicate格式
嘿,先帮你澄清个小细节:你写的anArray其实更像是一个NSDictionary哦,因为它是用键值对(identifier1、identifier2)组织的,不是数组的有序结构~接下来给你两种解决方案,其中一种完全不用循环也不需要Predicate,比你想的更简单!
解决方案
最简洁的实现(无需Predicate,无手动循环)
你要的结果其实可以通过KVC的集合特性直接提取,步骤非常简单:
// 先把你的"anArray"改成更准确的命名,比如dataDict(因为它是字典类型) NSDictionary *dataDict = @{ @"identifier1": @{ @"3498239502323120": @{@"key1": @"abc", @"key2": @123}, @"3493208429034821": @{@"key1": @"def", @"key2": @456} }, @"identifier2": @{ @"456434234234": @{@"key1": @"ghi", @"key2": @789}, @"8796554": @{@"key1": @"jkl", @"key2": @101112} } }; // 1. 取出identifier1对应的子字典 NSDictionary *identifier1SubDict = dataDict[@"identifier1"]; // 2. 提取所有子字典的key1值,自动完成遍历 NSArray *filteredArray = [identifier1SubDict.allValues valueForKey:@"key1"]; // 此时filteredArray就是 @[@"abc", @"def"]
这个方法利用了KVC对集合的自动遍历能力,不需要你写任何循环或Predicate,直接得到目标数组。
用NSPredicate的实现(如果一定要用Predicate)
其实NSPredicate的核心作用是过滤数组中符合条件的元素,而不是直接提取属性值。如果硬要用Predicate来实现,你需要先把字典的所有值转成数组,再配合Predicate(这里因为要所有元素,所以Predicate只是匹配全部),最后提取属性:
NSDictionary *identifier1SubDict = dataDict[@"identifier1"]; NSArray *valuesArray = identifier1SubDict.allValues; // 定义Predicate:匹配所有元素(TRUEPREDICATE代表恒真) NSPredicate *predicate = [NSPredicate predicateWithFormat:@"TRUEPREDICATE"]; // 过滤数组(这里其实是保留所有元素) NSArray *filteredValues = [valuesArray filteredArrayUsingPredicate:predicate]; // 提取所有元素的key1值 NSArray *filteredArray = [filteredValues valueForKey:@"key1"];
如果后续你需要过滤特定条件的key1值(比如只取key1等于@"abc"的项),Predicate的格式就有意义了,比如:
// 只保留key1等于abc的元素 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"key1 == %@", @"abc"]; NSArray *filteredValues = [valuesArray filteredArrayUsingPredicate:predicate]; NSArray *filteredArray = [filteredValues valueForKey:@"key1"]; // 结果为 @[@"abc"]
补充:你的原代码问题点
你原代码里的anArray[identifier]存在两个问题:
- 你的数据源是
NSDictionary,不是NSArray,所以正确的取值方式是dataDict[@"identifier1"]; - 取出来的结果是
NSDictionary类型,不能直接调用filteredArrayUsingPredicate:(这个方法是NSArray的),必须先通过allValues转成数组才行。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

