reduce()最強説!?
JavaScriptのArrayメソッドは色々あり、以前いくつか復習したが、
今回はreduce()最強説を検証してみよう。
まずは復習から。
reduce()の基本的な使い方
reduce()はArrayの各要素に対して順番に指定した処理をして、最終的に1つの結果を返すメソッドである。previousV(Previous Value)には直前の処理の結果が入るが、初回処理のタイミングではまだ値が入っていないので、Initial Valueを指定しておくか、指定しなければarray[0]の値が入る(この場合currentVはarray[1]の値が入る。
const array = [1, 2, 3, 4];
// 初期値 0 + 1 + 2 + 3 + 4
const initialV = 0; // Initial Value
const result = array.reduce((previousV, currentV) => previousV + currentV, initialV);
console.log(result);
//Output: 10
他のメソッドをreduce()で置き換える
reduce()は非常に柔軟であり、他のArrayメソッドと組み合わせると、割となんでもできてしまう。
map()の代わり
mapの方が当然もっと見やすいコードを書けるが、ここではreduceのポテンシャルに注目して見ていく。
const numbers = [1, 2, 3, 4];
const doubled = numbers.reduce((accumulator, currentV) => {
accumulator.push(currentV * 2);
return accumulator;
}, []); //初期値に空のArray []を渡し、計算結果をpushしていく
console.log(doubled); // Output: [2, 4, 6, 8]
filter()の代わり
先ほどと同様だが、pushするかどうかの条件を付け足せばfilterと同じことが実現できる。
const numbers = [1, 2, 3, 4];
const evenNumbers = numbers.reduce((accumulator, currentV) => {
if (currentV % 2 === 0) {
accumulator.push(currentV);
}
return accumulator;
}, []);
console.log(evenNumbers); // Output: [2, 4]
find()の代わり
少しややこしいけどコメントと合わせて。
const numbers = [1, 2, 3, 4];
const target = 3;
const found = numbers.reduce((accumulator, currentV) => {
if (accumulator !== null) {
return accumulator; // 初期値はnullに設定しているのでtargetが見つかるまでここには来ない
}
if (currentV === target) {
return currentV;
}
//CurrentVがtargetと一致しない場合はnullがreturnされ続けるのでaccumulatorもnullが続く
return null;
}, null);
console.log(found); // Output: 3
確かにreduce()の守備範囲広い。
可読性は低いけど・・・。
他にもある!reduce()の便利な使い方
データを結合したり他の型に変換したりできる
Arrayの状態から要素を結合することができる。文字列に限らずオブジェクトなど必要な形に変換できる。
一つにまとめるのはreduceの得意技。
const words = ['Platypus', 'is', 'the', 'best'];
const combined = words.reduce((accumulator, currentV) => accumulator + ' ' + currentV);
console.log(combined); // Output: Platypus is the best
const items = [
{ id: 1, name: 'platypus' },
{ id: 2, name: 'kamonohashi' },
{ id: 3, name: 'ornitorrinco' }
];
const itemObject = items.reduce((accumulator, currentV) => {
accumulator[currentV.id] = currentV;
return accumulator;
}, {});
console.log(itemObject);
// Output: { '1': { id: 1, name: 'platypus' }, '2': { id: 2, name: 'kamonohashi' }, '3': { id: 3, name: 'ornitorrinco' } }
ネストされたArrayを一次元配列に変換する
const array = [[0, 1],[2, 3],[4, 5]]
const flattened = array.reduce((previousV, currentV) => previousV.concat(currentV),[]);
console.log(flattened);
// Output: [0, 1, 2, 3, 4, 5]
配列内の重複を除く
const array = ["P", "P", "l", "a", "l", "t", "t", "y", "t", "p", "u", "s"];
const arrayWithNoDuplicates = array.reduce(
(previousV, currentV) => {
if (!previousV.includes(currentV)) {
return [...previousV, currentV];
}
return previousV;
},
[],
);
console.log(arrayWithNoDuplicates);
// Output: ['P', 'l', 'a', 't', 'y', 'p', 'u', 's']
reduce()は最強か?
reduce()メソッドはその柔軟性においては確かに最強。
他のArrayメソッドと代替可能な点についても理解できた。
あとはコードの書きやすさと読みやすさを考慮しつつ、使いたい時に使うのが良さそう。
MDNでreduceについて確認していると配列内の重複を除く方法のところで気になる記載があった。
メモ:
引用元:MDNSet
とArray.from()
に対応している環境を使っている場合は、const arrayWithNoDuplicates = Array.from(new Set(myArray))
を使うことで重複要素を除去された配列を取得することができます。
何それ!?というわけで、次回は配列内の重複を除く方法について見ていく予定。
カモノハシが生息するオーストラリアにも台風は来るのかしら。
日本ほど頻繁には来ないが、サイクロンが大きな被害をもたらすことがあるらしい。
サイクロンという響きがなんか台風より強そう・・・
