【JavaScript / TypeScript】よく使う配列の反復処理まとめ

## はじめに
今回は、JavaScriptやTypeScriptでよく使う配列の反復処理をまとめてみようと思います。
ちなみに、社内プロジェクトではReact + TypeScriptを書くことが多く、もうReactといえばFunctional Componentの時代なので、必然的に関数型を意識して書くことになります。
関数型プログラミングとは何か？という話はここでは割愛しますが、配列の反復処理がうまくできることは、自然と関数型プログラミングのお作法を身につける一歩となると筆者は思っています。

以下では、TypeScriptで書く想定で話を進めます。

### ちなみに宣伝★
弊社では、今回のようなJavaScript / TypeScriptを利用した開発プロジェクトはもちろんのこと、
様々な開発プロジェクトがあり、ご協力いただけるフリーランスエンジニアの方を募集しています！
**（★サーバーサイド、フロントエンド、ネイティブアプリ等、どんなポジションも大大歓迎中）**

興味がある方は、ぜひ下記フォームに回答いただけますと幸いです！
👉 フォームは[こちら](https://docs.google.com/forms/d/e/1FAIpQLSfY9lckFjAJ_Ddc4rdHDSIFoV4NFHw1q2HriK2aa_jvVhp8QQ/formResponse)

## 全体理解
配列の反復処理は、「元の配列から何が生まれるか」を意識すると理解が進みます。
特にTypeScriptで書くのであれば、返り値の型を意識するだけで、理解度が変わってくると思います。
以下でも、そういった観点を踏まえて説明していきたいと思います。

## 注意
以下の例では反復処理内の関数の引数を`ele`（`reduce()`の場合は`acc`と`cur`）としていますが、
この引数は基本的に自分で決めるものです。必ずしも同じにする必要はありません。
また、処理内の引数を増やすことでそのループでの引数を定義できますが、今回は割愛します。
詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)を参照してください。

## `map()`： 元の配列と同じ要素数の配列を返す
`map()`メソッドは、元の配列のそれぞれの要素に対して共通の処理を行います。そして、それぞれの要素に対する処理は、他の要素の値に影響しません。なので、必然的に同じ要素数の配列を出力します。
```ts
const arr = [1, 2, 3, 4];

const result = arr.map((ele) => ele * 2);

console.log(result);
// [ 2, 4, 6, 8 ]
```

## `filter()`: 元の配列から条件に合致した要素のみ抽出して返す
まず、`filter()`も返すものは配列です。しかし、条件に合うもののみ抽出するので、配列の要素数は元の配列の要素数以下となります。
```ts
const arr = [1, 2, 3, 4];

const arr2 = arr.filter((ele) => ele % 2 === 0);

console.log(arr2);
// [ 2, 4 ]
```
ちなみに、関数内の返り値が条件式になり、その判定で抽出されるか否か決まりますが、条件式は基本的に`true`か`false`のどちらかとなり、`true`のもののみ反映されます。つまり、返り値がtrueと見なされる要素が抽出されます。
```ts
const arr = [1, 2, 3, 4];

const result = arr.filter(() => true);

console.log(result);
// [ 1, 2, 3, 4 ]
```

## `find()`: 元の配列から条件に最初に合致した要素を返す
`filter()`と違い、`find()`の結果は該当する最初の要素で、配列ではなくなります。（元の配列の要素が配列ならば別です。）
```ts
const arr = [1, 2, 3, 4];

const result = arr.find((ele) => ele % 2 === 0);

console.log(result);
// 2
```

## `some()`: 元の配列の要素のどれか一つでも`true`なら、`true`を返す
`boolean`型の値が返ってきます。内部の処理は、条件式に合致する要素が一つでもあるか否かで返り値が変わります。
```ts
const arr = [1, 2, 3, 4];

const result1 = arr.some((ele) => ele <= 2);

console.log(result1);
// true

const result2 = arr.some((ele) => ele > 5);

console.log(result2)
// false
```

## `every()`:  元の配列の要素の全てが`true`なら、`true`を返す
`some()`と同じく`boolean`型の値を返します。異なるのは内部の処理で、要素全てが条件式に合致するかで結果が変わります。
```ts
const arr = [1, 2, 3, 4];

const result1 = arr.every((ele) => ele <= 4);

console.log(result1);
// true

const result2 = arr.every((ele) => ele <= 2);

console.log(result2)
// false
```

## `reduce()`: これまでの計算結果を引き継いで処理し、ループし切ったらその計算結果を返す
1つのループの中で、それまでの処理の結果（`acc`）とそのループでの対象の要素（`cur`）に対して処理を加えます。以降のループでも同じように処理を繰り返すこととなります。これまでの他の反復処理と違い、それ以前の結果もそれ以降の処理に影響してきます。
結果の値の型は、必然的に関数内の返り値の型に一致します。
```ts
const arr = [1, 2, 3, 4];

const result = arr.reduce((acc, cur) => acc + cur);

console.log(result);
// 10
```

## まとめ
いかがでしたか？
冒頭でも述べましたが、配列の反復処理は、「元の配列から何が生まれるか」を意識するをお勧めします。（筆者の個人的意見では）
この記事を辞書的に使っていただいて、習得の役に立てれば幸いです！
**お問い合わせやご意見がありましたら、お気軽にご連絡ください！**

## おわりに
繰り返しになりますが、弊社では、フリーランスエンジニアの方を募集しております！

熱意を持って新しいプロジェクトに挑戦したい方、様々な大規模開発プロジェクトに興味のある方は、下記フォームにてあなたの経歴をご回答ください！

👉 フォームは[こちら](https://docs.google.com/forms/d/e/1FAIpQLSfY9lckFjAJ_Ddc4rdHDSIFoV4NFHw1q2HriK2aa_jvVhp8QQ/formResponse)

たくさんのご応募、お待ちしております！