Swiftには主に3つの標準コレクションがあります:Array、Set、Dictionary。それぞれ異なるインターフェースを実現し、内部構造が異なり、異なる目的に適しています。
この質問の背景:
Swiftのコレクションは、型安全性(type safety)とパフォーマンスに重点を置いて設計されており、Array/Set/Dictionaryにおける値のセマンティクスとコピーバイライト(Copy-on-Write)が含まれています。
問題:
しばしば初心者の開発者は、SetやDictionaryを使用すべき場所にArrayだけを使用し、メモリの無駄遣いやアクセス/検索速度の低下を招きます。違いを理解する必要があります。
解決策:
要素の順序付きコレクション、インデックスによるアクセスが可能で、重複を許可します。通常は動的バッファによって実装されます。
ユニークな要素(Hashable)の順序なしコレクション。ハッシュによるアクセスは非常に高速で、重複は許可されません。
キーと値のペアのコレクション。キーはHashableである必要があります。ハッシュテーブルを通じてキーによる値へのアクセスが可能です。
コード例:
var arr: [Int] = [1, 2, 3, 4] var set: Set<Int> = [1, 2, 2, 3] var dict: [String: Int] = ["a": 1, "b": 2] // set == [1, 2, 3] — 重複は除外されます
主な特徴:
SetやDictionaryの要素としてnon-Hashable型を使用できるか?
いいえ。Set/Dictionaryに格納するための要素はHashableである必要があります(ユニークなハッシュ識別子を持つ必要があります)。そうでない場合、コンパイラはコレクションの作成を許可しません。
struct Point {} // Set<Point>はエラーを引き起こします。なぜならPointはHashableではないからです
Setの要素の保存順序は追加した順序と同じか?
いいえ。Setは順序を保証せず、イテレーションが任意の順序を返す可能性があります。順序が必要な場合はArrayを使用してください。
Dictionaryで存在しないキーにアクセスしようとした場合はどうなるか?
DictionaryはOptionalを返します。注意が必要です — 存在しないキーでのアクセスはnilを返し、エラーにはなりません。
let val = dict["not exist"] // val — nil
開発者はユニークなユーザーリストのためにArrayを使用し、containsでユニーク性を探します。大きなリストでは多くの時間がかかります。
長所:
短所:
同じリストがSetとして実装されています。存在確認は瞬時で、ユニークな値が保証されます。
長所:
短所: