# 集合 | Set型

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

# 集合の宣言方法

Swiftでは、集合は次のフォーマットで書くことができます。

let a: Set<Element> = 値

次の例では、Int型の要素を含む集合を生成しています。

let a: Set<Int> = [1,2,3]

# 型推論

Swiftは、集合に含む要素から型を推論できるので、宣言時にはElement型を省略して Set だけで書くことができます。

let a: Set = [1,2,3]

空の集合を定義する場合は、値の型推論ができないため、明示的に型を指定する必要があります。

let a: Set<Int> = []

# 空の集合

空の集合は、イニシャライザを使って次のように書くこともできます。

let a = Set<Int>()

# 集合の特徴

Swiftの集合の特徴は以下になります。

# 一意な値を格納する

集合は、重複した値を持たないので、同じ値を入れてもスキップされます。

let a: Set = [1,2,3,1,2,3]

a // [1,2,3]

また、集合演算が使えるので、union で和集合を行うことができます。次の例では、同じ値をマージさせて一つの集合を生成しています。

let a: Set = [1,2,3]
let b: Set = [1,2,3,4,5,6,7]

let c = a.union(b)

c // [1,2,3,4,5,6,7]

# 順序関係は保証されない

集合は、繰り返される要素の順番は保証されません。

for-in文で、繰り返し処理を実行すると、実行環境によってその順番が変わります。

let a: Set = [1,2,3]

for value in a {
  print(value))
}

// 実行環境によって順番は変わる
// 1回目
// 1
// 3
// 2

// 2回目
// 3
// 2
// 1

# 集合要素へのアクセス

集合要素へのアクセスは、メソッドやプロパティを使って、アクセスすることができます。

# contains

contains は、指定した値があるか調べることができます。値がある場合は、true を返し、値がない場合は、false を返します。

let a: Set = [1,2,3]

let b = a.contains(1) // true
let c = a.contains(100) // false

# description

description は、集合の情報を取得することができます。

let a: Set = [1,2,3]

let b = a.description // [1, 2, 3]

# count

集合要素の要素数を調べるには、count を使うことができます。

let a: Set = [1,2,3]

let b = a.count // 3

# isEmpty

集合が空かどうがを調べるには、isEmpty を使うことができます。空の場合は、true を返し、要素をがある場合は false を返します。

let a = Set<Int>()

a.isEmpty // true

let b: Set = [1,2,3]

b.isEmpty // false

# 集合要素の追加

集合の要素を追加するには、insert を使うことができます。

var a: Set = [1,2,3]

a.insert(100)

a // [3, 2, 1, 100]

# 集合要素の削除

集合の要素を追加するには、remove を使うことができます。

var a: Set = ["Dog","Cat","Rabbit"]

a.remove("Dog")

a // ["Cat", "Rabbit"]

# 集合演算

Swiftでは、提供されているメソッドを使って、集合演算を行うことができます。

# 和集合 | union

和集合を求めるには、union を使います。次の例では、値を一意にして集合を生成しています。

let a: Set = [1,2,3]
let b: Set = [1,2,3,4,5]

// 値を一意にする
let c = a.union(b) // [1,2,3,4,5]

変数に破壊的な変更をしたい場合は、formUnion を使います。

let a: Set = [1,2,3]
let b: Set = [1,2,3,4,5]

a.formUnion(b)

print(a) // [1,2,3,4,5]

# 差集合 | subtracting

差集合を求めるには、subtracting を使います。次の例では、差分かある値のみ抽出して集合を生成しています。

let a: Set = [1,2,3]
let b: Set = [1,2,3,4,5]

// 差分かある値のみ抽出する
let c = b.subtracting(a) // [4,5]

変数に破壊的な変更をしたい場合は、subtract を使います。

var a: Set = [1,2,3]
var b: Set = [1,2,3,4,5]

b.subtract(a) 

print(b) // [4,5]

# 積集合 | intersection

積集合を求めるには、intersection を使います。次の例では、同じ値のみ抽出して集合を生成しています。

let a: Set = [1,2,3]
let b: Set = [1,2,3,4,5]

// 同じ値のみ抽出する
let c = a.intersection(b) // [1,2,3]

変数に破壊的な変更をしたい場合は、formIntersection を使います。

var a: Set = [1,2,3]
var b: Set = [1,2,3,4,5]

a.formIntersection(b)

print(a) // [1,2,3]

# 等しいか調べる

== 演算子 を使用すると、2つの集合がすべて同じ値を含むかどうかを判定することができます。全て同じ値を含む場合はtrueを返し、一つでも異なる場合はfalseを返します。

var a: Set = [1,2,3]
var b: Set = [1,2,3]

a == b // true

一つでも要素が異なると、falseを返します。

var a: Set = [1,2,3]
var b: Set = [1,2,3,4]

a == b // false

# 含まれているか調べる

集合の中に、ある集合が含まれているか判定することができます。

# サブセット | isSubset

isSubset は、集合のすべての要素が特定の集合に含まれているかどうかを判定することができます。

次の例では、a の要素は全て b の集合に含まれているのでtrueを返します。

var a: Set = [1,2,3]
var b: Set = [1,2,3,4]

a.isSubset(of: b) // true

# スーパーセット | isSuperset

isSuperset は、ある集合が特定の集合に含まれているかどうかを判定することができます。

次の例では、ba の集合に含まれているのでtrueを返します。

var a: Set = [1,2,3]
var b: Set = [1,2,3,4]

b.isSuperset(of: a)   // true

# isDisjoint

isDisjoint は、共通する要素がない場合にtrueを返し、一つでも含まれていたらfalseを返します。

次の例では、ab の集合には共通の要素がないのでtrueを返します。

var a: Set = [1,2,3]
var b: Set = [4,5,6]

a.isDisjoint(with: b)   // true

一つでも共通の値が含まれると、falseを返します。

var a: Set = [1,2,3]
var b: Set = [3,4,5,6]

a.isDisjoint(with: b)   // false