Setを使いこなしたい（願望）

Swiftの配列はみなさんだいたい`Array`クラスを使ってるかと思いますが、`Set`クラスも結構良いですよという紹介です。

# Setとは
Objective-Cでは`NSSet`クラスでしたね

## 要素の重複を許さない
Setクラスの特徴は、配列の要素の重複を許さないところです
`["日本", "アメリカ", "日本", "中国"]`という`Array`があった場合、`日本`が重複しているのですが、`Set`では、`["日本", "アメリカ", "中国"]`になります。

## 順番は関係ない
たまにデメリットになることもあるかもしれませんが、`Set`は要素の順番を考えません。
なので、`["日本", "アメリカ", "中国"]`と入れた場合、`["中国", "日本", "アメリカ"]`という順番で入ります（順番の定義は不明です。ごめんなさい。

# 初期化
`Set`の初期化（init）方法です
`Array`の場合とあまり変わらないですが、`Set`を入れる変数にSet型を指定してあげないといけませんのでそこは注意が必要です

```swift
let array = ["日本", "アメリカ", "中国"] // Arrayクラスができる

// 変数にSet型を定義
let set: Set = ["日本", "アメリカ", "中国"]
// Arrayと同様に要素の型も指定できる
let set_str: Set<String> = ["日本", "アメリカ", "中国"]

// 空の配列で初期化
let set_empty_1 = Set<String>()
let set_empty_2:Set<String> = []
```

# 要素操作

## 要素の追加
`Array`クラスでは、`append()`で追加しましたね

```swift
var array = ["日本", "アメリカ", "中国"]
array.append("ロシア") // ["日本", "アメリカ", "中国", "ロシア"]
```

`Set`クラスでは、`insert()`を使います

```swift
var set: Set<String> = ["日本", "アメリカ", "中国"]
set.insert("ロシア") // ["ロシア", "日本", "アメリカ", "中国"]
```

## 要素の削除
`Array`クラスでは、要素を検索してから削除でしたね

```swift
var array = ["日本", "アメリカ", "中国", "ロシア"]
let index = array.index(of: "ロシア")
array.remove(at: index!)
```

`Set`クラスでは、要素を直接削除しに行きます
その要素がなかった場合、nilが返されますので、そこで要素が削除されたかどうかを判断すると良いかと思います

```swift
var set: Set<String> = ["日本", "アメリカ", "中国", "ロシア"]
set.remove("ロシア") // ["日本", "アメリカ", "中国"]
set.remove("メキシコ") // nilが返り値としてきます
```

## 要素を含むかどうか
`Array`クラスも`Set`クラスも一緒です

```swift
var array = ["日本", "アメリカ", "中国"]
array.contains("アメリカ") // true

var set: Set<String> = ["日本", "アメリカ", "中国"]
set.contains("メキシコ") // false
```

# 論理演算
`Set`クラスには論理演算用のメソッドがあります(論理演算については[wiki](https://ja.wikipedia.org/wiki/論理演算)参照)

[公式ドキュメント](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html#//apple_ref/doc/uid/TP40014097-CH8-ID105)から画像をお借りして...説明して行きます
![setVennDiagram_2x.png](https://qiita-image-store.s3.amazonaws.com/0/150615/e0b169a5-f82a-ad5a-c1c5-24350e472487.png)

## 論理積(intersection)
`a`と`b`で同じ要素だけの集合ですね

```swift
let a:Set = [0, 1, 2, 3]
let b:Set = [2, 3, 4, 5]
a.intersection(b) // [2, 3]
```

## 論理和(union)
`a`と`b`の合成ですね（`a`と`b`に重複する要素は1つしか含まれません）

```swift
let a:Set = [0, 1, 2, 3]
let b:Set = [2, 3, 4, 5]
a.union(b) // [0, 1, 2, 3, 4, 5]
```

## 排他的論理和(symmetricDifference)
`a`と`b`の合成から、`a`と`b`で重複している要素を抜いたものですね

```swift
let a:Set = [0, 1, 2, 3]
let b:Set = [2, 3, 4, 5]
a.symmetricDifference(b) // [0, 1, 4, 5]
```

## 逆非含意(subtracting)
`a`から、`a`と`b`で重複している要素を抜いたものですね

```swift
let a:Set = [0, 1, 2, 3]
let b:Set = [2, 3, 4, 5]
a.subtracting(b) // [0, 1]
```

# 等式
`Array`クラスと同様に配列の要素を比べることができます

```swift
let a:Set = [0, 1, 2]
let b:Set = [0, 1, 3]
let c:Set = [0, 1, 2]

a == b // false
a == c // true

a != b // true
```

# 包含関係
配列に他の配列が含まれるかどうかを確認することができます

## サブセット
`b.isSubset(of: a)`は、`b`は`a`に含まれているかですね

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

b.isSubset(of: a) // true
c.isSubset(of: a) // false
```

## スーパーセット
`a.isSuperset(of: b)`は、`a`は`b`を含んでいるかですね

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

a.isSuperset(of: b) // true
a.isSuperset(of: c) // false
```

## スーパーセットで、同じではないか
`b.isStrictSubset(of: a)`は、`b`は`a`に含まれていれば`true`。しかし、`a`と`b`が同じなら`false`ですね

```swift
let a:Set = [0, 1, 2, 3, 4, 5]
let b:Set = [0, 1, 3]
let c:Set = [6, 7]
let d:Set = [0, 1, 2, 3, 4, 5]

b.isStrictSubset(of: a) // true
c.isStrictSubset(of: a) // false
d.isStrictSubset(of: a) // false
```

## スーパーセットで、同じではないか
`a.isStrictSuperset(of: b)`は、`a`は`b`を含んでいれば`true`。しかし、`a`と`b`が同じなら`false`ですね

```swift
let a:Set = [0, 1, 2, 3, 4, 5]
let b:Set = [0, 1, 3]
let c:Set = [6, 7]
let d:Set = [0, 1, 2, 3, 4, 5]

a.isStrictSuperset(of: b) // true
a.isStrictSuperset(of: c) // false
a.isStrictSuperset(of: d) // false
```

## 違うか
`a.isDisjoint(with: b)`は、`a`と`b`で同じ要素がないかですね

```swift
let a:Set = [0, 1, 2, 3, 4, 5]
let b:Set = [0, 1, 3]
let c:Set = [6, 7]
let d:Set = [0, 1, 2, 3, 4, 5]

a.isDisjoint(with: b) // false
a.isDisjoint(with: c) // true
```

# 最後に
これでみなさんもSetマスターですね笑
それでは、`Have a nice Swift Day!!`