从NSMutableArray获取唯一项目

时间:2010-06-03 20:03:12

标签: objective-c nsmutablearray nsarray

我今天有一个关于Objective-C的问题涉及NSMutableArray。来自.net / c#背景我在处理这些事情时遇到了一些麻烦。

假设我有一个名为“Song”的对象

我的歌有3个属性:

  • 标题
  • 艺术家
  • 类型

我有一个NSMutableArray或NSArray,它拥有我所有的Song对象。

我将如何尝试“查询”我的数组以获得仅包含(唯一)艺术家或流派的新数组。

在.net中你会用DISTINCT子句编写一个简单的LINQ查询,如何在Objective-C中解决这个问题?我猜测谓词,但我很难找到解决方案。

提前致谢。

6 个答案:

答案 0 :(得分:36)

你也可以使用:

NSArray *uniqueArtists = [songs valueForKeyPath:@"@distinctUnionOfObjects.artist"];
NSArray *uniqueGenres = [songs valueForKeyPath:@"@distinctUnionOfObjects.genre"];

同样,如果你需要比较整个对象,你可以创建一个新的readonly属性,它动态地组合你想要匹配的值(通过哈希或其他方式)并比较:

NSArray *array = [songs valueForKeyPath:@"@distinctUnionOfObjects.hash"];

注意:请记住,这会返回指定属性的唯一值,而不是对象本身。所以它将是一个NSString值的数组,而不是Song值。

答案 1 :(得分:13)

根据“独特艺术家”的含义,有几种不同的解决方案。如果您只想获得所有艺术家并且不希望任何人出现多次,请执行[NSSet setWithArray:[songArray valueForKey:@"artist"]]。如果你的意思是想要设置所有歌曲的列表,这些歌曲是他们的艺术家唯一的歌曲,你需要先找到只做一首歌的艺术家,然后找到那些艺术家的歌曲:

NSCountedSet *artistsWithCounts = [NSCountedSet setWithArray:[songArray valueForKey:@"artist"]];
NSMutableSet *uniqueArtists = [NSMutableSet set];
for (id artist in artistsWithCounts)
    if ([artistsWithCounts countForObject:artist] == 1])
        [uniqueArtists addObject:artist];
NSPredicate *findUniqueArtists = [NSPredicate predicateWithFormat:@"artist IN %@", uniqueArtists];
NSArray *songsWithUniqueArtists = [songArray filteredArrayUsingPredicate:findUniqueArtists];

答案 2 :(得分:5)

或者像这样:

filterTags  = [[NSSet setWithArray:filterTags] allObjects];

filterTags一开始并不是唯一的,但在手术后变得独一无二。

答案 3 :(得分:3)

这可能不是直接适用的,但它是创建一组独特价值的解决方案...... 假设您有一个具有多个重复条目的NSMutable事件数组。该数组名为eventArray。 NSSet对象可用于修剪该数组,然后重新填充该数组,如下所示...

NSSet *uniqueEvents = [NSSet setWithArray:eventArray];

[eventArray removeAllObjects];

[eventArray addObjectsFromArray:[uniqueEvents allObjects]];

答案 4 :(得分:3)

使用NSOrderedSet代替NSSet。

NSOrderedSet *uniqueOrderedSet = [NSOrderedSet setWithArray:itemsArray];
[itemsArray removeAllObjects];
[itemsArray addObjectsFromArray:[uniqueOrderedSet allObjects]];

答案 5 :(得分:-2)

我为Objective-C创建了一个简单的查询API,使这种任务变得更加容易。使用Linq-to-ObjectiveC distinct方法,检索具有独特艺术家的歌曲将涉及以下内容:

NSArray* songsWithUniqueArtistists = [input distinct:^id(id song) {
    return [song artist];
}];

这将返回一个歌曲实例列表,每个歌曲实例都有一个独特的艺术家。