集合は、順序を持たないコレクションで、同じ型でユニークな値を格納します。順序が重要でないときや、値をユニークにしておく必要があるときに、配列の代わりに集合を使うことができます。

NOTE

Swift の Set 型は、Foundation の NSSet クラスとつながっています。

Foundation と Cocoa での Set の使用についての詳細は、『Using Swift with Cocoa and Objective-C』を確認してください。

集合型のハッシュ値

集合に格納するためには、ハッシュ可能な型である必要があります。つまり、型が自身のハッシュ値を算出できる手段を持っている必要があります。ハッシュ値は、a == b が a.hashValue == b.hashValue となるように、すべてのオブジェクトを同じように比較するために Int 値です。

Swift の基本的な(StringIntDoubleBool のような)型は、すべてデフォルトでハッシュ可能で、集合の値や、辞書のキーとして使用できます。(Enumerations で説明されているように)関連値 (associated values) の無い列挙型 (enum) の case 値も、デフォルトでハッシュ可能です。

NOTE

Swift 標準ライブラリの Hashable プロトコルに準拠させることで、独自の型を集合の値や辞書のキーに使用することができます。Hashable プロトコルに準拠する型は、Int を返す hashValue プロパティが必要です。型の hashValue プロパティによって返される値は、同じプログラムでの異なる実行間、あるいは異なるプログラム間で同じになるとは限りません。

Hashable プロトコルは Equatable に準拠しているため、準拠する型は等価演算子 (==) の実装が必要です。Equatable プロトコルは、等価関係の == に準拠する実装を必要とします。== の実装は、次に示す 3 つの条件(abc の値すべて)を満たす必要があります。

  • a == a(反射性)
  • a == b ならば b == a(対称性)
  • a == b && b == c ならば a == c(推移性)

プロトコル準拠についての詳細は、Protocols を確認してください。

集合型シンタックス

Swift での集合の型は、Element が集合に格納できる値の型としたとき、Set<Element> と記述します。配列と違い、集合には同等の簡略形式がありません。

空集合を生成、初期化

イニシャライザシンタックスを使用して、型を持つ空の集合を生成することができます。

var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// "letters is of type Set<Character> with 0 items." と出力
NOTE

変数 letters の型は、イニシャライザの型により Set<Character> と推論されます。

関数の引数や、型が指定されている変数や定数のように、すでに型の情報がわかっている場合には、空の配列リテラルで空集合を生成することができます。

letters.insert("a")
// letters には Character 型の値が 1 件
letters = []
// letters は空集合になったが、型は Set<Character> のまま

配列リテラルで集合を生成

1 つ以上の値を簡略的な方法で記述する配列リテラルでも、集合を初期化することができます。

次の例は、String の値を格納する集合 favoriteGenres を生成します。

var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres を 3 件の初期値で初期化

変数 favoriteGenres は、Set<String> と記述し、「String 値の集合」として宣言します。この集合は、値の型を String と指定しているので、String 値のみ格納することができます。集合 favoriteGenres は、配列リテラルで記述された String 値 ("Rock""Classical""Hip hop") で初期化されています。

NOTE

集合 favoriteGenres は、以降の例で追加、削除されるため、定数 (let) ではなく、変数 (var) で宣言されています。

集合を配列リテラルから推論することはできないため、型 Set は明示的に宣言する必要があります。一方で、Swift の型推論により、同じ型の値を持つ配列リテラルで初期化する場合には、集合の型を記述する必要はありません。favoriteGenres の初期化を、より短い形式で記述することができます。

var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]

配列リテラル内のすべての値が同じ型であるため、Swift は変数 favoriteGenres の正しい型が Set<String> であると推論することができます。

集合のアクセスおよび変更

集合のメソッドやプロパティを利用して、集合にアクセス、または集合を変更します。

集合内の件数は、読み取り専用の count プロパティで確認します。

print("I have \(favoriteGenres.count) favorite music genres.")
// "I have 3 favorite music genres." と出力

count プロパティが 0 かを確認する簡単な方法として、ブール値を返す isEmpty プロパティを利用します。

if favoriteGenres.isEmpty {
    print("As far as music goes, I'm not picky.")
} else {
    print("I have particular music preferences.")
}
// "I have particular music preferences." と出力

集合に新しい値を追加するには、集合の insert(_:) メソッドを呼び出します。

favoriteGenres.insert("Jazz")
// favoriteGenres には値が 4 件

集合の remove(_:) メソッドを呼び出して、集合から値を削除することができます。メソッドは削除した値を返すか、値が集合のメンバーに含まれていなければ nil を返します。removeAll() メソッドで、集合からすべての値を削除することができます。

if let removedGenre = favoriteGenres.remove("Rock") {
    print("\(removedGenre)? I'm over it.")
} else {
    print("I never much cared for that.")
}
// "Rock? I'm over it." と出力

集合が特定の値を含んでいるかを確認するには、contains(_:) メソッドを利用します。

if favoriteGenres.contains("Funk") {
    print("I get up on the good foot.")
} else {
    print("It's too funky in here.")
}
// "It's too funky in here." と出力

集合内を繰り返し処理

集合内の値を forin ループで繰り返し処理することができます。

for genre in favoriteGenres {
    print("\(genre)")
}
// Classical
// Jazz
// Hip hop

forin ループについての詳細は、For-In Loops を確認してください。

Swift の Set 型は順序を持ちません。集合内の値を特定の順に繰り返し処理するには、< 演算子でソートされた配列として集合の要素を返す sort() メソッドを使用します。

for genre in favoriteGenres.sort() {
    print("\(genre)")
}
// Classical
// Hip hop
// Jazz

Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.