2010-06-03 50 views
11

我有一個關於目前涉及NSMutableArray的Objective-C的問題。來自.net/c#背景我在處理這些事情時遇到了一些麻煩。從NSMutableArray獲取獨特的項目

比方說,我有一個名爲 「宋」

我的歌有3個屬性的對象:

  • 標題
  • 藝術家
  • 類型

我有一個NSMutableArray的或NSArray將持有我所有的歌曲對象。

我該如何去試圖'查詢'我的數組,以獲得只有(唯一)藝術家或流派的新陣列。

在.net中,你會用DISTINCT子句編寫一個簡單的LINQ查詢,如何在Objective-C中解決這個問題?我正在用謂詞猜測,但正在努力尋找解決方案。

在此先感謝。

+3

歡迎來到1990 – 2010-06-03 20:05:07

回答

12

根據「獨特藝術家」的含義,有幾種不同的解決方案。如果你只是想讓所有的藝術家,並不想讓任何人出現不止一次,只要做[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]; 
+0

所以,讓我們說,我們在排列 - 其中包括 - 一個藝術家的兩首歌曲。然後,根據@「artist IN%@」謂詞,所有兩個出現在songsWithUniqueArtists數組中。我更喜歡使用NSMutableDictionary,並添加具有唯一鍵的對象。 – blyabtroi 2016-04-14 08:44:25

33

你也可以使用:

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

同樣的,如果你需要(通過散列或以其他方式)動態對比,你可以創建一個合併要匹配的值的新的只讀屬性的整個對象和對比較:

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

注意:請記住,這將返回指定屬性的唯一值,而不是對象本身。所以它將是一個NSString值的數組,而不是Song值。

+1

非常好;注意valueForKeyPath的警告:@「@ distinctUnionOfObjects.the_property」不保留排序順序。 – 2011-12-07 22:13:48

+0

任何方式獲取歌曲值而不是字符串 – Nitesh 2013-12-23 11:11:30

+0

如果你想要不同的對象,你應該使用一個集合在接受的答案。您可以使用-setWithArray初始值設定項將數組轉換爲一個集合(或者更好,如果可能,從一開始就從一個集合開始)。您還可以使用-isEqual和-hash來覆蓋用於確定對象唯一性的默認機制。 – Luke 2013-12-27 03:32:53

3

這可能不是直接適用的,但它是創建一組唯一值的解決方案... 假設您有一個具有多個重複條目的NSMutable數組事件。這個數組被命名爲eventArray。該的NSSet對象可用於修剪該數組,然後重新填充該數組,如下圖所示...

NSSet *uniqueEvents = [NSSet setWithArray:eventArray]; 

[eventArray removeAllObjects]; 

[eventArray addObjectsFromArray:[uniqueEvents allObjects]]; 
-2

我已經創建了Objective-C的一個簡單的查詢API,使得這樣的任務輕鬆了許多。使用Linq-to-ObjectiveC distinct方法,檢索與獨特的藝術家的歌曲將涉及以下內容:

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

這首歌返回實例列表,每一個獨特的藝術家。

5

或者這樣:

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

filterTags是不是第一次唯一的,但在手術後變得獨特。

3

使用NSOrderedSet代替NSSet。

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