これは何?
Javascriptを書いていると、必ずと言っていいいほど配列操作が必要になってくる場面が多いため、復習がてらにmap, filter, forEach, find, findIndex
をピックアップして配列操作に必要な知識をまとめてみました!
map()
配列の順番通りに各要素に対して一度ずつ呼び出し新しい配列を生成
する
const numbers = [1, 2, 3, 4, 5];
const newNumbers = numbers.map(number => number * 2);
// 出力
console.log(newNumbers);
// [2, 4, 6, 8, 10]
返り値
- 結果からなる新しい配列
- 何もreturnしなかった場合は
undefined
になる
// 何もreturnしなかった場合
const numbers = [1, 2, 3, 4, 5];
const newNumbers = numbers.map(number => {
number * 2
});
// 出力
console.log(newNumbers);
// [undefined, undefined, undefined, undefined, undefined]
どんな時に使う?
既存の配列を加工して、新しい配列を作成したい時に便利。
const numbers = [1, 2, 3, 4, 5];
// forEachを使った場合
const newNumbers = [];
numbers.forEach(number => newNumbers.push(number * 2));
// map()を使った場合
const newNumbers = numbers.map(number => number * 2);
// 出力
console.log(newNumbers);
// [2, 4, 6, 8, 10]
上記のように、forEach()
を使うとわざわざ空の配列を用意する必要があるが、map()
だと空の配列を用意する必要なく、ダイレクトに加工した新しい配列を代入できる
使わない方がいいケース
新しく作成された配列を使わない場合は、mapではなくforEachやfor-ofを使用する。
- 返された配列を使用しない場合
- コールバックから値を返さない場合
要するに、配列内の要素を利用して処理を行いたいだけで、新しい配列なんかいらんわ!!って時はmapじゃなく、forEachやfor-ofを使っておけば良さそう。
filter()
条件に合う(trueを返す)要素全てを抽出し、新しい配列を生成する。
const dataset = [
{ id: "001", name: "aaa" },
{ id: "002", name: "bbb" },
{ id: "003", name: "ccc" },
{ id: "004", name: "aaa" },
];
const newDataset = dataset.filter(data => data.name === "aaa");
// 出力
console.log(newDataset);
// [{id: "001", name: "aaa"}, {id: "004", name: "aaa"}]
返り値
- 結果からなる新しい配列
- または、条件に合う要素がない場合は、
空の配列
を返す
// 条件に合う要素がない場合
const dataset = [
{ id: "001", name: "aaa" },
{ id: "002", name: "bbb" },
{ id: "003", name: "ccc" },
{ id: "004", name: "aaa" },
];
const newDataset = dataset.filter(data => data.name === "ddd");
// 出力
console.log(newDataset);
// []
どんな時に使う?
配列の中から、ある条件に合う要素全てを抽出し新しい配列として生成したい場合。
使わない方がいいケース
ある条件に合う最初の要素のみ抽出したい場合 → find()を使うべき
forEach()
配列内の各要素に対して昇順で、1回ずつ実行する。
const numbers = [1, 2, 3];
numbers.forEach (number => console.log(number));
// 出力
// 1
// 2
// 3
返り値
mapやreduceとは異なり返り値は常にundefined
。
// returnで返り値を代入した場合
const numbers = [1, 2, 3];
const newNumbers = numbers.forEach (number => {
return number * 3
});
// 出力
console.log(newNumbers);
// undefined
どんな時に使う?
- 返り値を必要とせず、配列内の要素を用いて何かしらの処理を行いたい時
- map()やfilter()などでは、実現したい処理を実装できない場合
使わない方がいいケース
- 配列のループ処理で、返り値を必要とする場合
- map()やfilter()などで実装できる場合
- ループ中に中断させるような処理の場合は、適切ではないため、 arrayのメソッドの
every()
,some()
,find()
,findIndex()
を使うように検討する。
基本的に、いきなりforEachを使うのではなく、map()やfilter()などの他のarrayメソッドを使えるか検討する方が良さそう!!!(可読性UPも見込める⬆️⬆️)
find()
ある条件に合う最初の要素の値を返す
const dataset = [
{ id: "001", name: "aaa" },
{ id: "002", name: "bbb" },
{ id: "003", name: "ccc" },
{ id: "004", name: "aaa" },
];
const newDataset = dataset.find(data => data.name === "aaa");
// 出力
console.log(newDataset);
// {id: "001", name: "aaa"}
上記の出力結果のように、最初に条件に合った要素を取得する。
truthy
な値を返すまで繰り返し処理が行われる。
truthy = Boolean コンテキストに現れた時に true とみなされる値
返り値
- 条件に合う最初の要素
- どの要素も条件に一致しない場合はundefined が返り値となる
// どの要素も条件に一致しない場合
const dataset = [
{ id: "001", name: "aaa" },
{ id: "002", name: "bbb" },
{ id: "003", name: "ccc" },
{ id: "004", name: "aaa" },
];
const newDataset = dataset.find(data => data.name === "ddd");
// 出力
console.log(newDataset);
// undefined
どんな時に使う?
条件に合う最初の要素を1つだけ取得したい時
明示的に1つだけの要素を探していますよ〜と表現したい時(可読性UP⬆️)
使わない方がいいケース
条件に合う複数の要素を取得したい時 → filterを使用すべき
条件に当てはまる値が一意の値だと思っていたが、実は一意になってなかった場合 → filter()を使うべき
参考記事⬇️⬇️⬇️
【JavaScript】findメソッドの危険性についての考察
findIndex()
ある条件に合う最初の要素の位置を返す
const dataset = [
{ id: "001", name: "aaa" },
{ id: "002", name: "bbb" },
{ id: "003", name: "ccc" },
{ id: "004", name: "aaa" },
];
const newDataset = dataset.findIndex(data => data.name === "bbb");
// 出力
console.log(newDataset);
// 1
返り値
- 条件に合う最初の要素のindex番号(位置)
- どの要素も条件に一致しない場合は
-1
が返り値となる
// どの要素も条件に一致しない場合
const dataset = [
{ id: "001", name: "aaa" },
{ id: "002", name: "bbb" },
{ id: "003", name: "ccc" },
{ id: "004", name: "aaa" },
];
const newDataset = dataset.findIndex(data => data.name === "ddd");
// 出力
console.log(newDataset);
// -1
どんな時に使う?
条件に合う値のindex番号のみ取得したい場合
まとめ
基本的に配列の操作はforEach
でなんとかなるが、パッとみて処理の意図がわかるmap
やfilter
を使って配列操作をした方が、可読性が上がり、1行でかけたり、全体的なコード量も減ります。
配列操作の機会があったら、とにかくforEach
ではなくmap
やfilter
などで実装できないか検討してみてはいかがでしょうか??
この記事が検討の参考になれば幸いです!!!!