这个问题类似于从对象的NSArray中提取属性,但需要进行更深入的提取。
为了简单起见,我在下面的示例中提到的对象是NSStrings。
我有两个案子要解决。
具有对象的NSArray of NSArray of NSDictionary
最好使用键值编码,从以下结构中提取所有“标题”到一个可枚举的列表中:
NSArray *list1 = @[
@[
@{@"title":@"A", @"description":...},
@{@"title":@"B", @"description":...},
],
@[
@{@"title":@"C", @"description":...},
@{@"title":@"D", @"description":...},
],
];例如,所希望的结果是:
@[@"A", @"B", @"C", @"D"]NSArray of NSDictionary与NSArray of objects
最好是使用键值编码,从以下结构中,我希望将“标题”列表提取到一个可枚举的列表中:
NSArray *list2 = @[
@{
@"titles":@[
@"A",
@"B",
],
@"descriptions":...,
},
@{
@"titles":@[
@"C",
@"D",
],
@"descriptions":...,
},
];例如,所希望的结果是:
@[@"A", @"B", @"C", @"D"]备注
NSOrderedSet of NSOrderedSet of objects for first list和NSOrderedSet of NSDictionary与NSOrderedSet of objects of second list,但这不应该影响我认为的答案。for (... in ...)或enumateObjectWithBlock:。发布于 2015-08-03 07:27:04
在这种情况下,KVC确实可以通过一个名为集合操作符的@unionOfArrays来执行您的命令。这个操作符的一个效果是使数组变平,所以第一个例子非常简单。
[list1 valueForKeyPath:@"@unionOfArrays.title"]第二个非常相似,但你必须以相反的顺序去做。首先提取所有的titles数组,然后将它们扁平。
[list2 valueForKeyPath:@"titles.@unionOfArrays.self"]self是必要的--尽管它看起来是多余的--因为,根据上面链接的文档
除了
@count之外,所有集合操作符都需要一个指向集合操作符右侧的关键路径。
对于NSOrderedSet,您似乎可以在关键路径中使用它的array属性在对它们进行操作之前转换它们的内部集合,但是由于某种原因,这会产生错误。我发现这个有趣的小贴士,然而,贴在论尼古拉斯·布利奥德的“GitHub”上
// Convert each OrderedSet to an Array to mute the error.
NSLog(@"union : %@",[data valueForKeyPath:@"@distinctUnionOfArrays.values.@array"]);这个奇怪的@array操作符适用于您的NSOrderedSet示例输入:
NSOrderedSet *list1 = [NSOrderedSet orderedSetWithObjects:[NSOrderedSet orderedSetWithArray:@[ @{@"title":@"A"}, @{@"title":@"B"} ]], [NSOrderedSet orderedSetWithArray:@[ @{@"title":@"C"}, @{@"title":@"D"} ]], nil];
// Note also converting outer set to array first
NSLog(@"%@", [list1.array valueForKeyPath:@"@unionOfArrays.title.@array"]);
NSOrderedSet *list2 = [NSOrderedSet orderedSetWithArray:@[ @{ @"titles":[NSOrderedSet orderedSetWithObjects: @"A", @"B", nil] }, @{ @"titles":[NSOrderedSet orderedSetWithObjects: @"C", @"D", nil] } ]];
// Note also converting outer set to array first
NSLog(@"%@", [list2.array valueForKeyPath:@"titles.@unionOfArrays.self.@array"]);但我不知道为什么。我不知道这是从哪里来的,也不知道它在做什么(特别是在最后的原因)。
发布于 2015-08-03 09:01:48
感谢乔希对NSArray的回答。当我问我的问题时,我用NSArray描述了它,因为用现代的@[]语法编写起来更容易。我无法想象NSArray最合适的答案是不兼容的与实际的NSOrderedSet。
所以,我的真实情况更接近于:
NSOrderedSet *list1 = [NSOrderedSet orderedSetWithObjects:[NSOrderedSet orderedSetWithArray:@[ @{@"title":@"A"}, @{@"title":@"B"} ]], [NSOrderedSet orderedSetWithArray:@[ @{@"title":@"C"}, @{@"title":@"D"} ]], nil];
NSOrderedSet *list2 = [NSOrderedSet orderedSetWithArray:@[ @{ @"titles":[NSOrderedSet orderedSetWithObjects: @"A", @"B", nil] }, @{ @"titles":[NSOrderedSet orderedSetWithObjects: @"C", @"D", nil] } ]];我唯一能找到的NSOrderedSet解决方案是可悲的使用循环:
NSMutableOrderedSet *listA = [NSMutableOrderedSet orderedSet];
for (NSOrderedSet *set in [list1 valueForKey:@"title"]) {
[listA unionOrderedSet:set];
}
NSMutableOrderedSet *listB = [NSMutableOrderedSet orderedSet];
for (NSDictionary *object in list2) {
[listB unionOrderedSet:object[@"titles"]];
}编辑:很明显,乔希找到了一个无文件的@array操作符来解决这个问题。Contratz!
https://stackoverflow.com/questions/31780983
复制相似问题