出発点
重複をなくした配列が欲しいときに以下のようなコードを使うけれど、そういえばちゃんと理解していない。
なんかよくわからんけど重複をなくしてくれる魔法のコード的に使っていたのだが、さすがに情けないので勉強する。
const arr = [1, 2, 2, 3]
const arr2 = Array.from(new Set(arr));
// もしくは
const set = new Set(arr);
const arr3 = [...set]
Setってなに?
[Set(MDN)]
(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set)によると、
Set オブジェクトは、プリミティブ値・オブジェクト参照を問わず、あらゆる型で一意の値を格納できます
となっている。
特徴として、JavaScript Setオブジェクトでは、以下の2点が挙げられている。
- 値が一意であることが保証されている
- 順序を持たず、インデックスでアクセスできない
なるほど、ユニークな値を持つことを保証したものに変換することで重複を排除しているのか!
Array.fromと...(スプレッドオペレーター)はなんのため?
とりあえず、重複を排除するところまでは理解できた。さらに進めて重複を排除したあとに、Arrayに戻している理由は何なのだろう?
JavaScript: Sets vs. Arraysでは利便性のためとされていた。
Sets do not support functional programming methods like map, filter, and reduce so it’s often convenient to convert them to Arrays for processing.
mapやfilterといったメソッドが使えず、先述の特徴にあったインデックスでのアクセスもできないとなると使い勝手が悪いのは想像に難くない。
あれ? じゃあSetっていつ使う?のという疑問が湧いてくる。
Setはいつ使うのか?
これについても、さきほどのJavaScript: Sets vs. Arraysで例を挙げて紹介されており非常にわかりやすかったので簡単に紹介する。
Setは、くどいようだが値がユニークということが保証されている。つまり、ダブってほしくないものを格納しておくのに使うと便利だ。先程の記事では、ブログのカテゴリーがそうしたものの例として挙げられている。
ArrayではなくSetを使うことでダブっていないことが自動的に
保証される。そのため、if文とincludedなどを組み合わせて格納してもいい値かどうかをいちいち調べる必要がないのである。めちゃ便利!
まとめ
- Setの特徴を利用して重複を排除している
- mapとかでさらに加工するには使いにくいからArrayに戻すと便利
- Setは重複してほしくない値の格納の処理をより効率的に書けるので重複排除の魔法のフレーズにしておくのはもったいない