简体   繁体   English

从NSDrray的NSArray的NSArray中提取特性

[英]extracting properties from NSArray of NSArray of NSDictionary

This question is similar to extracting properties from NSArray of objects , but for deeper extraction. 此问题类似于从NSArray对象中提取属性 ,但用于深度提取。

For the sake of simplicity, the objects I am referring to in the below examples are NSStrings. 为简单起见,我在下面的示例中引用的对象是NSStrings。

I have two cases I want to solve. 我有两个案例我想解决。

NSArray of NSArray of NSDictionary with objects 带有对象的NSArray NSArray的NSArray

Preferably with Key-Value-coding, from the following structure, I'd like to extract all the "title" into a single enumerable list: 最好使用键值编码,从以下结构中,我想将所有“标题”提取到单个可枚举列表中:

NSArray *list1 = @[
    @[
        @{@"title":@"A", @"description":...},
        @{@"title":@"B", @"description":...},
    ],
    @[
        @{@"title":@"C", @"description":...},
        @{@"title":@"D", @"description":...},
    ],
];

Desired result would be for example: 期望的结果将是例如:

@[@"A", @"B", @"C", @"D"]

NSArray of NSDictionary with NSArray of objects 带有NSArray对象的NSDictionary的NSArray

Preferably with Key-Value-coding, from the following structure, I'd like to extract the lists of "titles" into a single enumerable list: 最好使用键值编码,从以下结构中,我想将“标题”列表提取到一个可枚举列表中:

NSArray *list2 = @[
    @{
        @"titles":@[
            @"A",
            @"B",
        ],
        @"descriptions":...,
    },
    @{
        @"titles":@[
            @"C",
            @"D",
        ],
        @"descriptions":...,
    },
];

Desired result would be for example: 期望的结果将是例如:

@[@"A", @"B", @"C", @"D"]

Notes 笔记

  • My real cases involve NSOrderedSet of NSOrderedSet of objects for first list and NSOrderedSet of NSDictionary with NSOrderedSet of objects for second list, but that shouldn't affect the answers I think. 我的真实情况涉及NSOrderedSetNSOrderedSet对象的第一个列表和NSOrderedSetNSDictionaryNSOrderedSet对象的第二个列表,但这不应该影响我认为的答案。

  • I wrote I would prefer to use key-value-coding, but that is not a must. 我写道,我更喜欢使用键值编码,但这不是必须的。 I just want to avoid, if possible, writing for (... in ...) or enumateObjectWithBlock: . 我只是想避免,如果可能的话,写for (... in ...)enumateObjectWithBlock: .

  • Again that shouldn't matter, but objects are NSManagedObject from fetch requests. 同样,这应该不重要,但对象是来自获取请求的NSManagedObject。 So I know I could just optimise the fetch requests directly, but I still want to know if there are nice alternatives. 所以我知道我可以直接优化获取请求,但我仍然想知道是否有很好的选择。

KVC can indeed do your bidding in this case, via a Collection Operator called @unionOfArrays . 在这种情况下,KVC确实可以通过名为@unionOfArraysCollection运算符进行 @unionOfArrays One effect of this operator is to flatten arrays, so your first example is very simple. 此运算符的一个作用是展平数组,因此您的第一个示例非常简单。

[list1 valueForKeyPath:@"@unionOfArrays.title"]

The second is quite similar, but you have to do it in the reverse order. 第二个非常相似,但你必须按相反的顺序进行。 First extract all the titles arrays, then flatten them. 首先提取所有titles数组,然后展平它们。

[list2 valueForKeyPath:@"titles.@unionOfArrays.self"]

The self is necessary -- although it seems redundant -- because, per the doc linked above self是必要的 - 虽然看似多余 - 因为,根据上面链接的文档

All the collection operators, with the exception of @count , require a key path to the right of the collection operator. @count ,所有集合运算符都需要集合运算符右侧的键路径。

For NSOrderedSet , it would seem that you could use its array property in the key path to convert the inner collections before operating on them, but for some reason this produces errors. 对于NSOrderedSet ,似乎您可以在键路径中使用其array属性来转换内部集合,然后再对它们进行操作,但由于某种原因,这会产生错误。 I found this interesting tidbit, however, posted on GitHub by Nicolas Bouilleaud : 我找到了这个有趣的小贴士,然而, 由Nicolas Bouilleaud发布在GitHub上

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

and this weird @array operator works on your NSOrderedSet sample input: 这个奇怪的@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"]);

but I have no idea why . 我不知道为什么 I can't figure out where this comes from or what it's doing (why it's at the end, in particular). 我无法弄清楚它来自何处或它正在做什么(特别是为什么它最后)。

Thank you Josh for the answer regarding NSArray. 感谢Josh关于NSArray的答案。 When I asked my question, I described it using NSArray because it was easier to write with the modern @[] syntax. 当我问我的问题时,我使用NSArray描述它,因为用现代的@[]语法编写它更容易。 I couldn't imagine that the most appropriate answer for NSArray would be incompatible with my real case of NSOrderedSet . 我无法想象,为NSArray的最合适的答案会是我的真实情况不符 NSOrderedSet

So, my real case is closer to that: 所以,我的真实案例更接近于此:

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

And the only solutions for NSOrderedSet I could find are sadly using a loop: 我能找到的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"]];
}

[edit: apparently Josh found an undocumented @array operator to solve the issue. [编辑:显然Josh找到了一个无证的@array运算符来解决这个问题。 Contratz!] Contratz!]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM