2013-06-26 26 views
7

我有一個NSMutableArrayoldArray。現在,有一次,這個NSMutableArray對象被另一個NSMutableArray更新,其可能具有與先前的NSMutableArray更多,更少或相同數量的元素。查找NSArray/NSMutableArray更改的索引

我想比較舊陣列和新陣列的變化。我想要的是兩個NSArray s addedArrayremovedArray它將包含已添加和/或從舊數組中刪除元素的索引。

這整個問題會更加明瞭用一個例子:

oldArray = {@"a",@"b",@"d",@"e",@"g"}; 

newArray = {@"a",@"c",@"d",@"e",@"f",@"h"}; 

所以,在這裏去除的各目標分別爲@「b」和@「G」在索引1和4。並且在索引1,4和5處添加的對象是@「c」,@「f」和@「h」(第一個對象被刪除,然後添加)。

因此,

removedArray = {1,4}; and addedArray = {1,4,5}; 

我希望有一個有效的方式來獲得這兩個數組 - 從新NSMutableArrayremovedArrayaddedArray。謝謝!如果問題不能理解,我願意提供更多信息。

編輯1

也許如果我解釋我想用這個東西它會更加明朗。

實際上我使用的是在tableview加載後用方法insertRowsAtIndexPathsremoveRowsAtIndexPaths更新UITableView,以便用戶可以看到被刪除的行出去並且新的行進入。tableview存儲用戶可以添加或刪除的收藏夾元素。所以在添加一些收藏夾並刪除一些後,當用戶回到收藏夾桌面時,會顯示動畫。

編輯2

應該提到這較早,但在這兩個舊的和新的數組中的元素將在升序排列。只有刪除或添加事項的指標。訂單不能更改。恩。 {@「b」,@「a」,@「c」,@「d」}不能是數組。

+1

那麼,我已經嘗試迭代通過舊的和新的數組使用循環,如果條件,但它變得非常混亂和越野車。這適用於某些情況,而不適用於其他情況。我想知道是否有一些NSMUtableArray方法可以緩解我想要做的事情。 – aksh1t

+0

你真的需要添加和刪除對象的索引嗎?對我來說,這聽起來更像是NSSet的工作。或者NSMutableSet分別。你可以統一集合,從另一個集合中刪除一個集合,確定相交等。你可以從數組創建它們,反之亦然。但你會放棄指數。 –

+0

@HermannKlecker - 刪除和添加的元素的索引是我想要的。這些是使用方法'insertRowsAtIndexPaths'和'removeRowsAtIndexPaths'的tableview中的動畫。 – aksh1t

回答

5

我已經嘗試迭代舊的和新的數組使用循環,如果條件,但它變得非常混亂和越野車。

這不是一個簡單的問題。首先,請注意,它可能有多種解決方案:

a b c d 
b c d e 

兩個(a={0, 1, 2, 3}, r={0, 1, 2, 3})(a={3}, r={0})是有效的解決方案。您可能要尋找的是最小的解決方案。

獲得最小解決方案的一種方法是找到兩個序列的Longest Common Subsequence (LCS)。用於查找LCS的算法將告訴您兩個序列的哪些元素屬於LCS,哪些不屬於LCS。原始數組中不在LCS中的每個元素的索引都進入removed數組;新陣列中不在LCS中的元素索引將進入added陣列。

以下是幾個例子(I括號LCS的元素):

0 1 2 3 4 5 
(a) b (d) (e) g 
(a) c (d) (e) f h 

不LCS的的old項1和4;的new不是在LCS的項是1,4,和5

下面是另一個例子:

0 1 2 3 
a (b) (c) (d) 
(b) (c) (d) e 

現在added3removed0

+0

哦,怎麼樣我的愚蠢,但我應該在這個問題中提到它,舊的和新的陣列中的元素將總是以遞增的順序。 __b c d a__是不可能的。它只會按升序添加或刪除元素。我將編輯該問題。 – aksh1t

+0

@ aksh1t沒關係,LCS的算法將在任意序列上工作。 – dasblinkenlight

+0

@ aksh1t我編輯過,以確保兩個序列都是按升序排列。 – dasblinkenlight

3
  1. addedArray = newArray∖(newArray∩oldArray)

     = newArray ∖ ({@"a",@"c",@"d",@"e",@"f",@"h"} ∩ {@"a",@"b",@"d",@"e",@"g"}) 
         = newArray ∖ {@"a",@"d",@"e"}    
         = {@"a",@"c",@"d",@"e",@"f",@"h"} ∖ {@"a",@"d",@"e"} 
         = {@"c",@"f",@"h"}    
    
  2. removedArray = oldArray∖(oldArray∩newArray)

      = oldArray ∖ ({@"a",@"b",@"d",@"e",@"g"} ∩ {@"a",@"c",@"d",@"e",@"f",@"h"}) 
         = oldArray ∖ {@"a",@"d",@"e"} 
         = {@"a",@"b",@"d",@"e",@"g"} ∖ {@"a",@"d",@"e"} 
         = {@"b",@"g"} 
    

要查找陣列的交叉點,則可以查看以下SO帖子: Finding Intersection of NSMutableArrays

+3

@Filip每個問題都有一個漂亮,優雅,快速和不正確的解決方案。這是其中之一:)爲了看清楚它是不正確的,考慮當新數組是由單個元素旋轉的舊數組時,該算法會產生什麼結果:該算法會產生兩個空答案。 – dasblinkenlight

+0

這個,就像@dasblinkenlight所說的不符合我獲得索引的目的。實際上我使用的是在tableview加載後用動畫更新UITableView的方法'insertRowsAtIndexPaths'和'removeRowsAtIndexPaths',以便用戶可以看到被刪除的行出去並且新的行進入。 – aksh1t

1

如果兩個陣列以升序已經排序,可以找到的添加和刪除 元件與單迴路兩個陣列上(使用兩個獨立的指針到陣列):

NSArray *oldArray = @[@"a",@"b",@"d",@"e",@"g"]; 
NSArray *newArray = @[@"a",@"c",@"d",@"e",@"f",@"h"]; 

NSMutableArray *removedArray = [NSMutableArray array]; 
NSMutableArray *addedArray = [NSMutableArray array]; 

NSUInteger iold = 0; // index into oldArray 
NSUInteger inew = 0; // index into newArray 

while (iold < [oldArray count] && inew < [newArray count]) { 
    // Compare "current" element of old and new array: 
    NSComparisonResult c = [oldArray[iold] compare:newArray[inew]]; 
    if (c == NSOrderedAscending) { 
     // oldArray[iold] has been removed 
     [removedArray addObject:@(iold)]; 
     iold++; 
    } else if (c == NSOrderedDescending) { 
     // newArray[inew] has been added 
     [addedArray addObject:@(inew)]; 
     inew++; 
    } else { 
     // oldArray[iold] == newArray[inew] 
     iold++, inew++; 
    } 
} 
// Process remaining elements of old array: 
while (iold < [oldArray count]) { 
    [removedArray addObject:@(iold)]; 
    iold++; 
} 
// Process remaining elements of new array: 
while (inew < [newArray count]) { 
    [addedArray addObject:@(inew)]; 
    inew++; 
} 

NSLog(@"removed: %@", removedArray); 
NSLog(@"added: %@", addedArray); 

輸出:

 
removed: (
    1, 
    4 
) 
added: (
    1, 
    4, 
    5 
) 
+0

這正是我所做的(儘管for循環代替了while循環)。感謝你的回答!我接受了另一個答案,因爲它幫助我理解了解決方案。不管怎麼說,多謝拉。 – aksh1t