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) の複雑度となります。

…うーん、難しい。

includeshasで考えると、includesは配列内の全要素を順にチェックして指定した値を探すのに対し、hasはキーと値のペアを効率的に格納および検索するためのデータ構造であるはハッシュテーブルのように動作するため、要素の存在確認が早いとのこと。

なるほど。