【JavaScript】配列から配列や値を生成するには？

JavaScriptの配列（`Array`）には、配列から配列やそれ以外の値を生成するメソッドがたくさんあります。
すべて覚える必要はありませんが、**どんなことができるのか知っておく**と違うものがあります。

この記事ではそんなメソッドのち、個人的によく使うものをいくつか紹介します。

# 配列を生成する
まずは、配列から**新しい配列を生成する**メソッドたちです。
これらは配列に対して、何らかの処理をした新しい配列を返します。

## `map`
与えられた関数を**全ての要素に対して呼び出し**、その関数の戻り値を使った新しい配列を返します。

:::note warn
`Array`の`map`メソッドと、連想配列の`Map`オブジェクトは**全くの別物**です。
ややこしいですが、特に関連はありません。
:::

`map`メソッドは引数`callbackfn`に関数を取ります。
`callbackfn`は以下の引数で内部的に呼び出されます。

- `element`: 現在の要素
- `index`: 現在の要素のインデックス
- `array`: `map`が呼び出された配列（あまり使わない印象）

`callbackfn`の戻り値は新しい配列を生成するのに使われます。

例えば、数値の入った配列から、要素の数値を2乗した配列を取得できます。
このとき`callbackfn`は、引数`element`の値を2乗した値を返すようにします。

```js
const numbers = [1, 3, 5] // 数値の入った配列
// 要素を2乗した新しい配列を返す
numbers.map(n => n ** 2) // [1, 9, 25]
```

`map`メソッドは非常に汎用的で、本当にさまざまなことに使えます。
詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)をご覧ください。

## `filter`
与えられた関数を全ての要素に対して呼び出し、**`true`を返した要素のみにフィルター**した新しい配列を返します。

`filter`メソッドは引数`callbackfn`に関数を取ります。
この関数は[`map`](#map)と同じ引数で内部的に呼び出されます。

- `element`: 現在の要素
- `index`: 現在の要素のインデックス
- `array`: `filter`が呼び出された配列（あまり使わない印象）

例えば、数値の入った配列から偶数のみを抜き出すことができます。
このとき`callbackfn`は、引数`element`が偶数かどうかを示す`boolean`値を返すようにします。

```js
const numbers = [1, 3, 4, 6, 7]
// 偶数のみにフィルターする
numbers.filter(n => n % 2 === 0) // [4, 6]
```

詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)をご覧ください。

## `slice`
配列から**一部の位置を切り出し**た、新しい配列を返します。
このとき元の配列に影響はありません。

`slice`メソッドは以下の引数を取ります。

- `start`: 切り出しを開始するインデックス
    - この位置の要素は含む
    - 負の数の場合、最後から遡って数える
- `end`: 切り出しを終了するインデックス
    - この位置の要素は含まない
    - 負の数の場合、最後から遡って数える
    - 省略した場合、最後の要素までが切り出される

例えばこのように切り出せます。

```js
const numbers = [1, 4, 5, 7]

// 1番目から3番目（は含まない）を切り出す
numbers.slice(1, 3) // [4, 5]

// 2番目以降を切り出す
numbers.slice(2) // [5, 7]
```

詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)をご覧ください。

# 値を生成する
ここからは、配列から配列以外の値を生成するメソッドを紹介します。

ここでは以下のメソッドを紹介します。

- `join`
- `reduce`

## join
配列の要素を**連結**した**文字列**を返します。
これは文字列の生成に使えます。

例えばこのような感じです。

```js
const fluits = ['apple', 'orange', 'remon']
fluits.join() // 'apple,orange,remon'

console.log(`fluits: ${fluits.join()}`) // fluits: apple,orange,remon
```

なお、通常は配列の要素同士を`,`で繋ぎますが、何で連結するかは引数で指定できます。

```js
const fluits = ['apple', 'orange', 'remon']
fluits.join('&') // 'apple & orange & remon'
```

このメソッドは文字列の加工に使うことができます。
以下のような手順での加工は割と使うかもしれません。

1. [文字列の`split`メソッド](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split)で文字列を分解して配列にする
1. `map`メソッドなどで文字ごとに加工する
1. `join`で配列を繋げて再度文字列にする

<!-- いい例が思いつかなかった... -->

詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/join)をご覧ください。

## reduce
与えられた関数に基づいて配列を**縮小**します。
縮小というのは、特定の手順に基づいて**値を更新していく**感じです。

`reduce`メソッドは引数`callbackfn`に関数を取ります。
`callbackfn`は以下の引数で呼び出されます。

- `accumulator`: 前の呼び出しのときに返された値
- `currentValue`: 現在の値
- `currentIndex`: 現在の値のインデックス
- `array`: 呼び出されている配列

また、`callbackfn`の戻り値は、そのまま次の`accumulator`に渡されます。

`reduce`メソッドはよく、数値が入った配列の和を計算するのに使われます。

```js
const numbers = [1, 4, 5]
numbers.reduce((acc, cur) => acc + cur) // 10
```

上のコードはこのようなイメージです。
1. 要素の最初の値を`accumulator`の初期値する
1. `accumulator`と`currentValue`を足した数値を返す

詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)をご覧ください。