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)
上記のコードは少し紛らわしいように見えるかもしれませんが、内部では魔法は起こっていません。 reducer
メソッドにconsole.log
を追加して、accumulator
引数とitem
引数を出力してみましょう。
次のスクリーンショットは、コンソールに記録されたものを示しています。
したがって、最初に気付くのは、配列に3
値があるため、メソッドが3
回呼び出されることです。 アキュムレータは、reduce
に渡したinitialValue
である0
から始まります。 関数を呼び出すたびに、item
がaccumulator
に追加されます。 メソッドの最後の呼び出しのaccumulator
の値は15
で、item
は15
、15 + 15
は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つの強力なツールになる可能性があることを理解しています。