JavaScriptの配列には reduce() があります。
▼ Array.reduceメソッドのMDNでの解説
reduce() メソッドは、配列のそれぞれの要素に対して、順番通りに、ユーザーが提供した「縮小」コールバック関数を呼び出します。その際、直前の要素における計算結果の返値を渡します。配列のすべての要素に対して縮小関数を実行した結果が単一の値が最終結果になります。
引用元 : https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
この説明にもあるように・・・
「直前の要素における計算結果の返値」
要素それぞれに独自コールバックを実行し、
その結果を1つの単一値にできる便利なものです。
この表現だと意味不明だと思うので……
いくつかArray.reduceの実用例を紹介します!
このページの目次
実用例1.数字配列の合計値を求める
まずはreduce関数の分かりやすい使用例から
こういうケースを考えてみます。
- 数値を要素に持つ配列があるとする
- その要素(数値)を次々と足していく
- 最終的にその合計値(sum)を求めたい
普通だとループとか使いますよね。
でもreduce関数ならループ不要です。
▼ このようなコードで合計値計算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/// 1~10の数字配列 const nums = [ 1,2,3,4,5,6,7,8,9,10 ] /// それら合計値を計算 let sum = nums.reduce((sum,x)=>{ return sum + x }, 0) console.log('sum : ', sum) /// => sum : 56 /// アロー関数なしで書く場合… /* let sum = nums.reduce(function(sum,x){ return sum + x }, 0) */ |
このように配列に対してArray.reduceを使い、第1引数には1つ1つの要素に実行されるコールバック関数・第2引数には初期値を渡すだけです。
より詳しく説明するなら次の役割です。
- 第1引数 : コールバック関数
各要素に呼ばれる2つの引数を持つコールバック関数。1つめ引数には直前のコールバックで返された値が使用され、2つ目引数が各要素の値。この例だとコールバックが実行されるたびに sum に x が加算されていく。
- 第2引数 : 初期値
初めてコールバック関数が呼ばれるときのコールバック関数の第1引数の初期値。この例では 0 を渡している
このように配列要素に順々にコールバックを実行するだけじゃなく、その直前の結果を保持しながらループを回せるという代物です。
もしreduce()を使わずに合計値計算するならこうなる
仮にreduce()を使わずに書くとするなら……
▼ 同じ処理はループを使ってもかける
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/// 1~10の数字配列 const nums = [ 1,2,3,4,5,6,7,8,9,10 ] /// それら合計値を研鑽 let sum = 0 for(let i=0; i<nums.length; ++i){ sum += nums[i] } console.log('sum : ', sum) /// => sum : 56 |
これと先ほどのreduceは全く同じ処理です。
ループの方が分かりやすいですが、forループだとループ用の一時変数 i を用意する必要もあるし、配列に対して動的に実行できません。
ところがreduce関数だと配列に対してダイレクトに呼び出しできます。この点が色々便利なんですよね(単純なコードではメリットを実感しにくいかも)
使用例2.文字列に同じ文字が何回含まれるかカウント
こういうケースを考えてみます。
- 文字列 'Fizz Buzz' がある
- その中に 'z' が何回あるか調べたい
今まではループを使っていました。
これからは次のような書き方もできます。
▼ ある文字が何回含まれるかカウントするコード例
1 2 3 4 5 6 7 8 9 |
const text = "Fizz Buzz" const count = text.split('').reduce((num,ch)=>{ if(ch === 'z'){ num++ } return num }, 0) console.log(`'z' appears ${count} times`) /// => 'z' appears 4 times |
文字列を文字配列に分解してるのが text.split('') というコード。あとはコールバック内で文字が 'z' だった場合はカウントアップすればいいだけです。
ちなみに日本語もカウント可能
使用例3.rgb配列を16進数カラーコードに変換
今度は次のようなケースを考えてみます。
- 色の赤青緑を表しているrgb配列がある
- たとえば [255, 0, 0] のような配列
- それを #ff0000 のような16進数表記にしたい
このためだけにループは使いたくないです。
だからreduceメソッドを使って変換してみます。
▼ rgb配列をカラーコードに変換コード例
1 2 3 4 5 6 7 8 9 10 |
/// rgb配列 const rgb = [0, 172, 238] /// 16進数表記に変換 const hex = rgb.reduce((hex,v) => { return hex + v.toString(16).padStart(2,'0') }, '#') console.log('hex : ', hex) /// => #00acee |
ここでは v.toString(16) とすることでrgb各要素を16進数に変換。ただし1桁の数字を2桁に合わせるために padStart(2,'0') として調整してます。
もちろんループを使っても書けるものの……
ループよりも簡単にかけて便利じゃないですか?
それもreduce関数の実用的な使い方の1つです。
ここまでの Array.reduce() の実用例まとめ
最後にまとめて箇条書きしておきます。
アイデア次第では複雑な処理がシンプルに書けます。
もし他の実用例があれば教えてください。ではまた