首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSArray of NSArray of NSDictionary的性质提取

NSArray of NSArray of NSDictionary的性质提取
EN

Stack Overflow用户
提问于 2015-08-03 06:47:38
回答 2查看 626关注 0票数 4

这个问题类似于从对象的NSArray中提取属性,但需要进行更深入的提取。

为了简单起见,我在下面的示例中提到的对象是NSStrings。

我有两个案子要解决。

具有对象的NSArray of NSArray of NSDictionary

最好使用键值编码,从以下结构中提取所有“标题”到一个可枚举的列表中:

代码语言:javascript
复制
NSArray *list1 = @[
    @[
        @{@"title":@"A", @"description":...},
        @{@"title":@"B", @"description":...},
    ],
    @[
        @{@"title":@"C", @"description":...},
        @{@"title":@"D", @"description":...},
    ],
];

例如,所希望的结果是:

代码语言:javascript
复制
@[@"A", @"B", @"C", @"D"]

NSArray of NSDictionary与NSArray of objects

最好是使用键值编码,从以下结构中,我希望将“标题”列表提取到一个可枚举的列表中:

代码语言:javascript
复制
NSArray *list2 = @[
    @{
        @"titles":@[
            @"A",
            @"B",
        ],
        @"descriptions":...,
    },
    @{
        @"titles":@[
            @"C",
            @"D",
        ],
        @"descriptions":...,
    },
];

例如,所希望的结果是:

代码语言:javascript
复制
@[@"A", @"B", @"C", @"D"]

备注

  • 我的实际案例包括NSOrderedSet of NSOrderedSet of objects for first list和NSOrderedSet of NSDictionaryNSOrderedSet of objects of second list,但这不应该影响我认为的答案。
  • 我写到我更喜欢使用键值编码,但这不是必须的。如果可能的话,我只想避免编写for (... in ...)enumateObjectWithBlock:
  • 这也不重要,但是对象是从提取请求中提取的NSManagedObject。因此,我知道我可以直接优化获取请求,但我仍然想知道是否有不错的替代方案。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-03 07:27:04

在这种情况下,KVC确实可以通过一个名为集合操作符@unionOfArrays来执行您的命令。这个操作符的一个效果是使数组变平,所以第一个例子非常简单。

代码语言:javascript
复制
[list1 valueForKeyPath:@"@unionOfArrays.title"]

第二个非常相似,但你必须以相反的顺序去做。首先提取所有的titles数组,然后将它们扁平。

代码语言:javascript
复制
[list2 valueForKeyPath:@"titles.@unionOfArrays.self"]

self是必要的--尽管它看起来是多余的--因为,根据上面链接的文档

除了@count之外,所有集合操作符都需要一个指向集合操作符右侧的关键路径。

对于NSOrderedSet,您似乎可以在关键路径中使用它的array属性在对它们进行操作之前转换它们的内部集合,但是由于某种原因,这会产生错误。我发现这个有趣的小贴士,然而,贴在论尼古拉斯·布利奥德的“GitHub”

代码语言:javascript
复制
// Convert each OrderedSet to an Array to mute the error.
NSLog(@"union : %@",[data valueForKeyPath:@"@distinctUnionOfArrays.values.@array"]);

这个奇怪的@array操作符适用于您的NSOrderedSet示例输入:

代码语言:javascript
复制
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"]);

但我不知道为什么。我不知道这是从哪里来的,也不知道它在做什么(特别是在最后的原因)。

票数 3
EN

Stack Overflow用户

发布于 2015-08-03 09:01:48

感谢乔希对NSArray的回答。当我问我的问题时,我用NSArray描述了它,因为用现代的@[]语法编写起来更容易。我无法想象NSArray最合适的答案是不兼容的与实际的NSOrderedSet

所以,我的真实情况更接近于:

代码语言:javascript
复制
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解决方案是可悲的使用循环:

代码语言:javascript
复制
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!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31780983

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档