今日はSwiftのSet型について書いていこうと思います。
Set型とは
Set型とは配列に似た型です。
配列との違いですが、下の2点があります。
- 重複を許可しない
- 順番を保証しない
実際に試した所、重複削除がされて順番もセットしたものとは違っていました。
let set: Set = [1, 2, 3, 1, 2, 3]
for value in set {
print(value) // → 2, 3, 1
}
Set型の使いどころ
私がSetを使うのは下の2つのタイミングです。
それぞれについて説明していきます。
- 配列の重複削除をしたい時
- 配列間の差分を取りたい時
1. 配列の重複削除をしたい時
配列の重複削除は、下のように配列をSet型にしてからmapで配列を生成すればできます。
しかし順番が保証されない点は注意が必要です。
let arr = [1, 2, 3, 1, 2, 3]
print(Set(arr).map { $0 }) // → [2, 3, 1]
NSOrderedSetを使うと順番も保証する事ができます。
let arr = [1, 2, 3, 1, 2, 3]
print(NSOrderedSet(array: arr).map { $0 }) // → [1, 2, 3]
重複削除をSet以外で行う場合、reduceも使えます。
しかしOrderがnの2乗になるので可能ならSetを使った方が良さそうです。
let arr = [1, 2, 3, 3, 2, 1]
let result = arr.reduce([Int]()) { (var arr, element) -> [Int] in
if arr.contains(element) { return arr }
arr.append(element)
return arr
}
print(result)
2. 配列間の差分を取りたい時
Setでは以下の4種類のメソッドで2つのSetから要素を抽出します。
この中のsubtractを使えばSet1にはあるけどSet2にはない要素を抽出できます。
このメソッドを利用すれば配列間の差分を取得できます。
- intersect
- union
- subtract
- exclusiveOr
set1.intersect(set2) // → [2, 3]
set2.intersect(set1) // → [2, 3]
set1.union(set2) // → [2, 3, 1, 4]
set2.union(set1) // → [2, 3, 1, 4]
set1.subtract(set2) // → [1]
set2.subtract(set1) // → [4]
set1.exclusiveOr(set2) // → [4, 1]
set2.exclusiveOr(set1) // → [4, 1]
これはどういう時に使うかというと、ブログアプリでエントリーのタグ更新する時などがあります。
APIの仕様によってはタグが追加された場合は追加されたタグのIDを送り、タグが削除されたらそのタグのIDを送るというケースが出てきます。
そういう時にはSetを使えばスマートに送るべきパラメータを作る事ができます。