web-dev-qa-db-ja.com

NSArrayではなくNSSetを使用したほうがよいのはいつですか?

NSSetsをアプリで何度も使用しましたが、自分で作成したことはありません。

NSSet ではなく NSArray を使用したほうがよいのはいつですか?

111
geminiCoder

コレクション内のアイテムの順序が重要でない場合、セットを使用すると、コレクション内のアイテムを検索する際のパフォーマンスが向上します。

理由は、セットがハッシュ値を使用してアイテム(辞書など)を検索する一方で、配列が特定のオブジェクトを検索するためにコンテンツ全体を反復処理する必要があるためです。

167
Ole Begemann

Appleのドキュメント の画像は非常によく説明しています:

Objective-C Collections

Arrayは、要素のシーケンスordered(追加しても順序は維持されます)

[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];

[1, 2, 3, 4, 6, 4, 1, 2]

Setは、distinct(重複なし)、unordered要素のリスト

[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];

[1, 2, 6, 4, 3]
178
James Webster

これに対する最良の答えは、 Apple独自のドキュメント です。

enter image description here

主な違いは、NSArrayは順序付きコレクション用であり、NSSetは順序付けられていないコレクション用です。

this one のように、2つの速度の違いについて言及している記事がいくつかあります。順序付けられていないコレクションを繰り返し処理する場合、NSSetは素晴らしいです。ただし、多くの場合、NSArrayしかできないことを行う必要があるため、これらの能力の速度を犠牲にします。

NSSet

  • 主に比較によりアイテムにアクセスする
  • 順不同
  • 重複を許可しません

NSArray

  • インデックスでアイテムにアクセスできます
  • 順序付けられました
  • 重複を許可します

本当にそれだけです!それが役立つかどうか教えてください。

65
woz

NSOrderedSetはiOS 5以降で使用できるため、データ構造内でオブジェクトを複製するかどうかが主な違いになります。

12
Jason

NSArray

  1. データの順序付きコレクション
  2. 重複を許可します
  3. コレクション型オブジェクトです

NSSet

  1. 順不同のデータ収集
  2. 重複を許可しません
  3. コレクション型オブジェクトでもあります
9
iOS Lifee

配列は、インデックスによってアイテムにアクセスするために使用されます。任意のアイテムを配列に複数回挿入できます。配列は要素の順序を保持します。

セットは基本的に、アイテムがコレクション内にあるかどうかを確認するためにのみ使用されます。アイテムには順序やインデックスの概念はありません。セット内のアイテムを2回使用することはできません。

配列に要素が含まれているかどうかを確認する場合は、そのすべての項目を確認する必要があります。セットは、より高速なアルゴリズムを使用するように設計されています。

値のない辞書のようなセットを想像できます。

配列とセットだけがデータ構造ではないことに注意してください。他にもあります。キュー、スタック、ヒープ、フィボナッチのヒープ。アルゴリズムとデータ構造に関する本を読むことをお勧めします。

詳細については、 wikipedia を参照してください。

7
Sulthan
NSArray *Arr;
NSSet *Nset;

Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];

NSLog(@"%@",Arr);
NSLog(@"%@",Nset);

配列

2015-12-04 11:05:40.935 [598:15730](1、2、3、4、2、1)

セット

2015-12-04 11:05:43.362 [598:15730] {(3、1、2、5)}

5
abc221

主な違いは、他の回答ですでに与えられています。

セットとディクショナリの実装方法(つまり、ハッシュの使用)のため、キーに可変オブジェクトを使用しないように注意する必要があります。

キーが変更されると、ハッシュも(おそらく)変更され、ハッシュテーブル内の別のインデックス/バケットを指します。元の値は削除されず、サイズ/カウントの構造を列挙または要求するときに実際に考慮されます。

これにより、バグを見つけるのが非常に困難になる可能性があります。

4
joakim

ここNSArrayNSSetのデータ構造のかなり徹底した比較を見つけることができます。

短い結論:

はい、NSArrayはNSSetよりも高速であり、単に保持および反復するだけです。構築するのにわずか50%速く、反復するのに500%速くなります。レッスン:コンテンツの反復のみが必要な場合は、NSSetを使用しないでください。

もちろん、含めるかどうかをテストする必要がある場合は、NSArrayを避けるように努力してください。反復テストと包含テストの両方が必要な場合でも、おそらくNSSetを選択する必要があります。コレクションの順序を維持し、含めるかどうかをテストする必要がある場合は、それぞれが同じオブジェクトを含む2つのコレクション(NSArrayとNSSet)を保持することを検討する必要があります。

NSDictionaryは、キーデータをコピーする必要があるため、NSMapTableよりも構築に時間がかかります。検索を高速化することで、これを補います。もちろん、この2つの機能は異なるため、ほとんどの場合、この決定は他の要因で行う必要があります。

3
Che

通常は、アクセス速度が重要で順序が重要でない場合に設定を使用するか、他の手段で決定します(述語またはソート記述子を使用)。たとえば、コアデータは、管理対象オブジェクトが多対多の関係を介してアクセスされる場合にセットを使用します

2
iDevAmit

それを少し追加するために、配列から重複を削除するためにsetを使用することがあります:-

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values
1
dreamBegin