LoginSignup
16
19

More than 5 years have passed since last update.

Setの使いどころを書いてみる

Posted at

今日は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. 配列の重複削除をしたい時
  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を使えばスマートに送るべきパラメータを作る事ができます。

16
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
19