从 NSMutableArray 获取唯一项

发布于 2024-09-04 07:01:18 字数 372 浏览 2 评论 0原文

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

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

我的歌曲有 3 个属性:

  • 标题
  • 艺术家
  • 流派

我有一个 NSMutableArray 或 NSArray,其中包含我所有的 Song 对象。

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

在 .net 中,您将编写一个带有 DISTINCT 子句的简单 LINQ 查询,那么在 Objective-C 中如何解决这个问题呢?我正在用谓词进行猜测,但正在努力寻找解决方案。

I have a question about Objective-C today involving NSMutableArray. Coming from a .net/c# background I'm having some trouble working with these things.

Let's say I have an object called "Song"

My song has 3 properties:

  • Title
  • Artist
  • Genre

I have a NSMutableArray or NSArray which holds all my Song objects.

How would I go about trying to 'query' my array to get a new array with only (Unique) Artists or Genre's.

Where as in .net you would write a simple LINQ query with a DISTINCT clause, how would one solve this in Objective-C? I'm guessing with predicates but am struggling to find a solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

嗳卜坏 2024-09-11 07:01:18

您还可以使用:

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

同样,如果您需要比较整个对象,您可以创建一个新的只读属性,该属性动态组合要匹配的值(通过哈希或其他方式)并进行比较:

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

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

You could also use:

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

Likewise, if you need to compare the entire object you could create a new readonly property that combines the values you want to match on (via a hash or otherwise) dynamically and compare on that:

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

NOTE: Keep in mind this returns the uniques values for the specified property, not the objects themselves. So it will be an array of NSString values, not Song values.

温折酒 2024-09-11 07:01:18

根据“独特艺术家”的含义,有几种不同的解决方案。如果您只想获取所有艺术家并且不希望任何艺术家出现多次,只需执行 [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];

Depending on what you mean by "unique artists," there are a couple of different solutions. If you just want to get all the artists and don't want any to appear more than once, just do [NSSet setWithArray:[songArray valueForKey:@"artist"]]. If you mean you want to set a list of all the songs which are the only song by their artist, you need to first find the artists who only do one song and then find the songs by those artists:

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];
在梵高的星空下 2024-09-11 07:01:18

或者像这样:

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

filterTags一开始不是唯一的,但是操作后就变得唯一了。

Or like this:

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

filterTags was not unique at first, but becomes unique after the operation.

寒尘 2024-09-11 07:01:18

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

NSSet *uniqueEvents = [NSSet setWithArray:eventArray];

[eventArray removeAllObjects];

[eventArray addObjectsFromArray:[uniqueEvents allObjects]];

This may not be directly applicable but it is a solution to creating a unique set of values...
Assume you have a NSMutable array of events that have multiple duplicate entries. This array is named eventArray. The NSSet object can be used to trim that array and then repopulate that array as shown below...

NSSet *uniqueEvents = [NSSet setWithArray:eventArray];

[eventArray removeAllObjects];

[eventArray addObjectsFromArray:[uniqueEvents allObjects]];
空名 2024-09-11 07:01:18

使用 NSOrderedSet 而不是 NSSet。

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

Use NSOrderedSet instead of NSSet.

NSOrderedSet *uniqueOrderedSet = [NSOrderedSet setWithArray:itemsArray];
[itemsArray removeAllObjects];
[itemsArray addObjectsFromArray:[uniqueOrderedSet allObjects]];
守不住的情 2024-09-11 07:01:18

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

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

:返回歌曲实例列表,每个实例都有一个唯一的艺术家。

I've created a simple query API for Objective-C that makes this kind of task a lot easier. Using the Linq-to-ObjectiveC distinct method, retrieving songs with unique artists would involve the following:

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

This returns a list of song instances, each with a unique artist.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文