2013-06-26 11 views
7

私はNSMutableArrayoldArrayを持っています。さて、ある時点で、このNSMutableArrayオブジェクトは、NSMutableArrayと更新されます。これは、前のNSMutableArrayと同じ、またはより少ない、または同じ数の要素を持つことがあります。NSArray/NSMutableArray変更のインデックスを見つける

古いアレイと新しいアレイとを比較して変更したいと考えています。私が望むのは、2つのNSArrayaddedArrayremovedArrayであり、古い配列から追加されたり削除されたりした要素のインデックスを含みます。

この全体の問題は、例を用いてより明らかであろう。

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

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

そこで、ここで削除されたオブジェクトが、それぞれ、「B」と@「G」インデックス1及び4で@あります。そして、追加されたオブジェクトは、インデックス1,4,5(最初のオブジェクトが削除され、追加された)で@ "c"、@ "f"、および "h"古いものと新しいNSMutableArrayからremovedArrayaddedArray -

したがって、

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

は、私はこれら二つの配列を取得するための効率的な方法をしたいです。ありがとう!問題があまり理解できない場合、私はより多くの情報を提供したいと思います。

編集1

私は私がこれを使用したいのかを説明している場合、おそらくそれがより明確になります。

私はテーブルビューがロードされる後にユーザが削除行が出て行くと、新しい行がインチテーブルビューの店に来る見ることができるように、アニメーションを持つメソッドinsertRowsAtIndexPathsremoveRowsAtIndexPathsとのUITableViewを更新しているためにこれを使用しています実際にどのようなユーザーが追加または削除できるお気に入り要素。だからいくつかのお気に入りを追加し、いくつかを削除した後。ユーザーがお気に入りのテーブルビューに戻ると、アニメーションが表示されます。

編集2

は、この先に言及している必要がありますが、古いものと新しい配列の両方の要素を昇順になります。削除または追加事項のインデックスのみ。注文は変更できません。例。 {@ "b"、@ "a"、@ "c"、@ "d"}は配列にすることはできません。

+1

まあ、私は古いとループを使用して新しいアレイとIF条件を反復処理しようとしているが、それは本当に厄介とバギーなっています。これはいくつかのケースでは動作し、他のケースでは動作しません。私は何をしたいのかを緩和するNSMUtableArrayのメソッドがあるかどうか疑問に思っていました。 – aksh1t

+0

追加したり削除したオブジェクトのインデックスが本当に必要ですか?私にとって、これはNSSetのための仕事のように聞こえます。またはそれぞれNSMutableSetセットを統一したり、他のセットからセットを削除したり、交差などを識別したりすることができます。また、配列からそれらを作成することもできます。しかし、あなたは指標を失うだろう。 –

+0

@HermannKlecker - 削除された要素と追加された要素のインデックスは、すべて私が望むものです。それらは 'insertRowsAtIndexPaths'と' removeRowsAtIndexPaths'メソッドを使ってテーブルビュー内のアニメーション用です。 – aksh1t

答えて

5

私はループとif条件を使って古い配列と新しい配列を反復しようとしましたが、実際には乱雑でバグがあります。

これは単純な問題ではありません。まず、それは複数のソリューションを持っていることに注意:

a b c d 
b c d e 

両方(a={0, 1, 2, 3}, r={0, 1, 2, 3})(a={3}, r={0})が有効なソリューションです。おそらくあなたが探しているのは最小限のです。

最小限の解決策を得る1つの方法は、2つのシーケンスのうちLongest Common Subsequence (LCS)を見つけることです。 LCSを見つけるためのアルゴリズムは、2つのシーケンスのどの要素がLCSに属しているかを示します。 LCSにない元の配列の各要素のインデックスはremoved配列に入ります。 LCSにない新しい配列の要素のインデックスはadded配列に入ります。

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

oldのアイテムないLCS 1および4である;ここ

は、いくつかの例は、(私はLCSの要素を括弧)でありますnewの項目がLCSにここ1、4、および5

されていない別の例である:

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

今は3removed0あります。

+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"} 
    

配列の交差点を見つけるには、次のような投稿を見ることができます: Finding Intersection of NSMutableArrays

+3

@Filipあらゆる問題には、きれいで、エレガントで、速く、間違った解決策があります。これは間違いであることを確認するには、新しい配列が単一の要素によって回転された古い配列である場合に、このアルゴリズムがどのように生成するかを検討してください。 – dasblinkenlight

+0

@dasblinkenlightのように、インデックスを取得する目的は果たされません。実際に私がこれを使用しているのは、UITableViewをメソッド 'insertRowsAtIndexPaths'と' removeRowsAtIndexPaths'でアニメーションで更新して、tableviewがロードされた後に、削除された行が外に出て新しい行が入ってくるのを見ることができるようにすることです。 – 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

これはまさに私がやったことです。答えをありがとう!私は解決策を理解するのを助けたので、私はもう一つの答えを受け入れました。とにかく、ありがとう。 – aksh1t

関連する問題