JavaScriptのReduceメソッドの説明
序章
Reduce は、特にWebにある漠然とした説明では、理解するのが難しい方法です。 reduce
は状態管理でよく使用されるため、理解することには多くの利点があります( Redux を考えてください)。
JavaScriptのreduce
配列メソッドのシグネチャは次のとおりです。
arr.reduce(callback, initialValue);
用語
Reduceには、次のような用語が付属しています。 レデューサー&アキュムレータ 。 accumulator
は最後の値であり、reducer
は、1つの値に到達するために実行するアクションです。
reducer は1つの値と1つの値のみを返すため、reduceという名前になることを覚えておく必要があります。
次の典型的な例を見てください。
const value = 0; const numbers = [5, 10, 15]; for(let i = 0; i < numbers.length; i++) { value += numbers[i]; }
上記により、30
(5 + 10 + 15)が得られます。 これは問題なく機能しますが、代わりにreduce
を使用してこれを行うことができます。これにより、value
変数を変更する必要がなくなります。
以下のコードも30
を出力しますが、value
変数(現在はinitialValue
と呼んでいます)を変更しません。
/* this is our initial value i.e. the starting point*/ const initialValue = 0; /* numbers array */ const numbers = [5, 10, 15]; /* reducer method that takes in the accumulator and next item */ const reducer = (accumulator, item) => { return accumulator + item; }; /* we give the reduce method our reducer function and our initial value */ const total = numbers.reduce(reducer, initialValue)
上記のコードは少し紛らわしいように見えるかもしれませんが、内部では魔法は起こっていません。 accumulator
引数とitem
引数を出力するreducer
メソッドにconsole.log
を追加しましょう。
次のスクリーンショットは、コンソールに記録されたものを示しています。
したがって、最初に気付くのは、配列に3
値があるため、メソッドが3
回呼び出されることです。 アキュムレータは、reduce
に渡したinitialValue
である0
から始まります。 関数を呼び出すたびに、item
がaccumulator
に追加されます。 メソッドの最後の呼び出しのaccumulator
の値は15
で、item
は15
、15 + 15
は[X122X ]これが最終的な値です。 reducer
メソッドはaccumulator
とitem
を返すことに注意してください。
これは、reduce
の使用方法の簡単な例です。次に、より複雑な例を詳しく見ていきましょう。
Reduceを使用して配列をフラット化する
次の配列があるとしましょう。
const numArray = [1, 2, [3, 10, [11, 12]], [1, 2, [3, 4]], 5, 6];
そして、なんらかの奇妙な理由で、JavaScriptが.flat
メソッドを削除したため、この配列を自分でフラット化する必要があるとしましょう。
したがって、配列がどれほど深くネストされていても、任意の配列をフラット化する関数を記述します。
function flattenArray(data) { // our initial value this time is a blank array const initialValue = []; // call reduce on our data return data.reduce((total, value) => { // if the value is an array then recursively call reduce // if the value is not an array then just concat our value return total.concat(Array.isArray(value) ? flattenArray(value) : value); }, initialValue); }
numArray
をこのメソッドに渡して結果をログに記録すると、次のようになります。
これは、非常に一般的な操作を非常に簡単にする方法の良い例です。
もう1つの例を見てみましょう。
最後の例-オブジェクト構造の変更
それで、新しいポケモンゲームが出てきたら、次のようなポケモンオブジェクトの配列を送信するサーバーがあるとしましょう。
const pokemon = [ { name: "charmander", type: "fire" }, { name: "squirtle", type: "water" }, { name: "bulbasaur", type: "grass" } ]
このオブジェクトを次のように変更します。
const pokemonModified = { charmander: { type: "fire" }, squirtle: { type: "water" }, bulbasaur: { type: "grass" } };
その目的の出力を取得するには、次のようにします。
const getMapFromArray = data => data.reduce((acc, item) => { // add object key to our object i.e. charmander: { type: 'water' } acc[item.name] = { type: item.type }; return acc; }, {});
このようにメソッドを呼び出すと、次のようになります。
getMapFromArray(pokemon)
目的の出力が得られます。
コードサンドボックスはこちらで確認できます。
結論
一見すると、reduce
は、map
やfilter
のような他のJavaScript配列反復法よりも複雑に見えますが、構文、コアコンセプト、およびユース-ケースは、JavaScript開発者にとってもう1つの強力なツールになる可能性があることを理解しています。