new Set()ってなに?
先日ChatGPT
でコード生成したところ、new Set()
というオブジェクトが登場した。
そういえば使ったことあると思い調べてみると、JavaScriptの配列で重複したものを削除し、ユニークな配列を作成するで使っていた。どうやら配列を削除するのに使っていたよう。
実際に調べてみると、
Set オブジェクトは値のコレクションです。 Set に重複する値は格納出来ません。 Set 内の値はコレクション内で一意になります。
とのこと。
簡単に言うと「要素の重複を許可しない配列のこと」だと思う。
じゃあ、配列と何が違うのか。
配列と何が違うのか
配列との違いは、
- 重複を許さない
- インデックスでアクセスできない
- あとは追加とか削除とかのメソッドが異なる
- 高次関数(map, filter, reduce)を使用できない
という点。
重複を許さない
const setValue = new Set([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]);
console.log(setValue);
// [LOG]: Set (6) {1, 2, 3, 4, 5, 6}
このように重複した値はなかったことになる。
インデックスでアクセスできない
const setValue = new Set([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]);
console.log(setValue[0]);
// Element implicitly has an 'any' type because expression of type '0' can't be used to index type 'Set<number>'.
// Property '0' does not exist on type 'Set<number>'.
こんな感じでエラーがでる。
追加とか削除とかのメソッドが異なる
const setValue = new Set([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]);
// 追加
setValue.add(7);
// 削除
setValue.delete(1);
console.log(setValue);
// [LOG]: Set (6) {2, 3, 4, 5, 6, 7}
こんな感じ。
高次関数(map, filter, reduce)を使用できない
これはそのままの意味なので使えないというだけ。
メリットは?
聞く限り重複を削除するときにしか使い道が見つからない。
そこでメリットを調べてみた。
要素が含まれているかどうかを効率的に確認できるメソッド
has
があり、これは配列のincludes
メソッドよりも高速に動作する
とかなんとか要は配列よりも効率的であることが多いらしい。
つまりパフォーマンスを上げる時はSet
を使うべきっぽい。
ChatGPT曰く、
Set は、挿入や削除、存在確認の操作が平均的に O(1) の時間複雑度で行えます。これに対し、配列の操作は要素数に依存するため、最悪の場合 O(n) の複雑度となります。
…うーん、難しい。
includes
とhas
で考えると、includes
は配列内の全要素を順にチェックして指定した値を探すのに対し、has
はキーと値のペアを効率的に格納および検索するためのデータ構造であるはハッシュテーブルのように動作するため、要素の存在確認が早いとのこと。
なるほど。