【JavaScript】Setって何？

# Setとは？
`Set`オブジェクトは**集合**です。
**重複する値は入れられない**という特徴があります。

また、`Set`は`[Symbol.iterator]`メソッドを持つため[反復可能](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Iteration_protocols#反復可能プロトコル)（`Iterable`）です。

## 使い方
`Set`オブジェクトはコンストラクタから作成できます。

```js
const set = new Set()
```

第一引数に配列（反復可能オブジェクト）を入れることで、`Set`の初期値を設定することもできます。

```js
const array = [1, 4, 5]
const set = new Set(array)
```

### 配列の要素を一意にする
`Set`は要素の重複を許しません。
そのため、本来の使い方ではなさそうですが、配列の要素から**重複を削除する**目的でも使えます。

例えばこんな感じです。
```js
// 重複を削除したい配列
const array = [1, 2, 2, 5, 6 ,6];

const set = new Set(array);
[...set]; // [1, 2, 5, 6]
```

これは、`Set`が以下の特徴を持っているからできます。

- コンストラクタが反復可能オブジェクトを取る
- `Set`が**重複を許さない**
- `Set`自身が反復可能なので、[スプレッド構文](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax)で**配列に変換できる**

# よく使うメソッド
`Set`オブジェクトはいくつかのメソッドを持っています。
ここでは、その中でも個人的によく使うものを紹介します。

## [`add`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/add)
与えられた要素を追加します。

```js
const set = new Set()
set.add(1)
set.add(3)

set // Set(2) {1, 3}
```

なお、その要素がすでに`Set`オブジェクト内にあった場合、要素は追加されません。

```js
const set = new Set()
set.add(3)
set.add(3) // すでに追加した要素を追加

set // Set(1) {3}
```


## [`has`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/has)
与えられた要素が`Set`内に存在するかどうかを返します。
戻り値は`boolean`です。

```js
const set = new Set([1, 5])

set.has(1) // true
set.has(2) // false

set.add(2)
set.has(2) // true
```

## [`size`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/size)

:::note
メソッドではなくプロパティですが、ここで紹介します。
:::

`Set`の**要素数**を示すプロパティです。

```js
const set = new Set([1, 5, 6])
set.size // 3

set.add(2) // 要素を追加
set.size // 4
```

## [`delete`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/delete)
与えられた要素を`Set`から削除します。

```js
const set = new Set([1, 2, 3])
set.has(1) // true

set.delete(1) // 1を削除
set.has(1) // false

set.delete(3) // 3を削除
set // Set(1) {2}
```

## [`clear`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/clear)
`Set`から全ての要素を削除します。

```js
const set = new Set([1, 3, 5])
set.size // 3

set.clear()
set.size // 0
```

## [`forEach`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach)
各要素を使って**ループ**します。
与えられた関数（`callbackFn`）を全ての要素に対して適用するとも言います。

`callbackFn`は以下の引数で呼び出されます。

1. `element`: 要素
1. `index`: 要素のインデックス
1. `set`: `forEach`が呼び出されている`Set`オブジェクト自身

```js
const set = new Set([1, 2, 2, 3, 1, 4])
set // Set(4) {1, 2, 3, 4]

set.forEach(num => {
  console.log(`number: ${num}`)
})

// number: 1
// number: 2
// number: 3
// number: 4
```

# 集合として扱う

つい最近（2024年）、ECMAScriptに`Set`オブジェクトの**和集合や差集合を計算する**メソッドが追加されました。

例えば和集合（2つの集合を足す）は、`union`メソッドで計算できます。

```js
const set1 = new Set([1, 3, 5])
const set2 = new Set([2, 4])

const set3 = set1.union(set2) // 和集合を計算
set3 // Set(5) {1, 3, 5, 2, 4}
```

他にも以下のようなメソッドがあります。

- [`union`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/union): 和集合
- [`difference`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/difference): 差集合
- [`intersection`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/intersection): 交差
- etc...

詳細は[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set#set_の合成)をご覧ください。