2013-02-13 87 views
5

我有一個NSMutableArray,它具有實體類對象作爲其對象。 現在我想從中刪除不同的對象。考慮下面的例子在iPhone中使用NSPredicate從NSMutableArray獲取不同的實體對象sdk

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 1; 
entity.iUserName = @"Giri" 
[arr addObject:entity]; 

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 2; 
entity.iUserName = @"Sunil" 
[arr addObject:entity]; 

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 3; 
entity.iUserName = @"Giri" 
[arr addObject:entity]; 

現在,我通過刪除重複的iUserName想在Array只有兩個對象。我通過迭代知道方式,但是我希望它不會像predicate或其他方式那樣迭代它。 如果有人知道,那麼請幫助我。 我曾嘗試過使用[arr valueForKeyPath:@"distinctUnionOfObjects.iUsername"];,但它並沒有將我退休的對象返回給我。

此問題與先前提出的問題完全不同。以前問的問題是爲了獲得不同的對象是正確的,但他們使用循環&我不想這樣。我想從NSPredicate或其他避免循環的簡單選項中獲得。

+0

「in iphone sdk」 - 謝謝!自從有人正確使用它(而不是使用不恰當的「使用Xcode」術語)已經很長時間了。 – 2013-02-13 13:23:55

+0

我記得我已經解決了這樣的問題3-4次。所以不要害羞搜索/谷歌。 – 2013-02-13 13:28:18

+1

@AKV我想通過比較實體類對象中的實體來區分不同的元素。另外我想避免for循環。是否有可能通過謂詞或任何其他選項 – Girish 2013-02-13 13:32:20

回答

0

那麼你有幾個選擇(我可以想到)。

  1. 使用NSSet而不是NSArray。
  2. 使用for循環(但不想遍歷數組)
  3. 使用謂詞搜索iUserName可以在將名稱添加到數組之前查看該名稱是否存在。

喜歡的東西:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iUserName == 'Giri'"]; 
NSArray *searchArray = [arr filterUsingPredicate:predicate]; 
4

編輯:你不能做你想要什麼,而無需手動循環陣列上,並建立一個新的數組。下面的答案將不起作用,因爲它假定最多隻有兩個副本。

NSMutableArray *filteredArray = [NSMutableArray array]; 

for (Entity *entity in arr) 
{ 
    BOOL hasDuplicate = [[filteredArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", entity.iUserName]] count] > 0; 

    if (!hasDuplicate) 
    { 
     [filteredArray addObject:entity]; 
    } 
} 

這將在它構建它時查找過濾數組中的重複項。

開始原來的答案

不能使用NSSet因爲Entity情況下,將不得不在compareTo:返回NSOrderedSame,這不是一個好主意,因爲你不應該使用的名稱作爲唯一標識符。

您可以使用謂詞,但它們仍然會在O(n^2)時間內循環遍歷數組,而無需進行一些優化。

NSArray *filteredArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Entity *evaluatedObject, NSDictionary *bindings) { 
    return [[arr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", evaluatedObject.iUserName]] count] > 1; 
}]]; 

這將工作正常。您可以通過首先對iUserName屬性排序數組,並對排序後的數組執行線性掃描(當您看到第一個重複項時停止),使速度更快。如果您處理的是小樣本量(例如,在一萬個左右),那麼這是很多工作。這可能不值得你花時間,所以只需使用上面的代碼即可。

+0

我曾嘗試過您的解決方案,但它不起作用。我使用了下面的代碼:NSArray * filteredArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^ BOOL(Entity * entity,NSDictionary * bindings) {return [[arr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@「iUsername ==%@」,exercise .iUsername]] count]> 1; }]]; – Girish 2013-02-13 14:41:06

+0

這應該工作,是的。 – 2013-02-13 14:42:38

+0

我的數組包含14個元素,其中7個是常見的,因此它需要返回6個元素,但它返回13個元素。 – Girish 2013-02-13 14:47:49

相關問題