reduceの日本語訳が「減らします」なので、
意図通り1個のものに集約する用途として使ってください。
reduceは使い方によってはmapみたいな使い方も出来るとおもいます。
可能か不可能かで言えば可能ですね。
実際やってる事自体は単なるループな訳で、
acc.pushを2回以上叩けば配列の要素数は減るどころか増えますね。
if文でacc.pushをスキップすればfilterの代わりになるでしょう。
使い方によっては特に渡って来た数より少ない結果を返すということにもならないです。
それを言い出せばリスト操作系のメソッドはほぼ全て不要です。
filterもmapもforEachも必要ありません。
しかしコードは文章です。
マシンだけではなく、人間も読者の対象であり、メンテされるべき文章です。
もし読んだ小説内で「減らします」というタイトルで、
逆にどんどん増殖してたら読者はどう思いますか?
この作者、おかしなものでも食ってしまったのだろうか……と不安に思うのではありませんか?
まぁ、小説は読者を楽しませるものなので、そういうケースは無いとは言い切れません。
全て読み終わった後で、「あ、そのページでは気付かなかったけど、確かに登場人物減ってる……!?」というトリックに使われるケースもありますからね。
でも、ソースコードは報告文に近い文章なので、そういうトリックを使ってはいけません。
普通に書いて動かしたコードですら1ヶ月挟んだら読みづらくて敵わないのに、
そんな暗号書く奴が一緒のプロジェクトで仕事したくはありません。
フィルターをかけて少ない数のデータを返すことが前提の使い方が想定されてるのでしょうか?
要素数を減らす場合はfilterを使って下さい。
JavaScript
1const items = [
2 {id:1, name: 'buy milk', isDone: true},
3 {id:2, name: 'buy milf', isDone: false},
4 {id:3, name: 'buy silk', isDone: true},
5]
6const res = items
7 .filter(it => it.isDone)
8 .map(it => ({...it, hoge: 123}));
reduceはなぜreduceと呼ばれるのでしょうか?
配列を使って、一つの変数を転がしながら加工していくからです。
基本的には配列→プリミティブ型(NumberやString)、配列→オブジェクトに加工する目的で使うようにしてください。
配列→配列は基本的には使わないでください。
利用用途が多いので既に強力なメソッドが沢山用意されているため、干渉することが多いからです。
まぁ、reduceの動作は単なるループ構文と同じ事が出来るので最後の手段として使われるケースは多いのと、JavaScriptのリスト操作系のメソッドは大概貧弱なのでreduceの登場回数は多いですが、
出来るだけ使わないということを覚えておいて下さい。
LodashやRamda.js等の関数型プログラミング用のライブラリを利用することで、この安易なreduceを減らす事が出来ます。
最後にreduceの推奨される使い方をしながら、値の集計するコードを書いてみました。
JavaScript
1const users = [
2 {name: "taro", score: 100},
3 {name: "jiro", score: 80},
4 {name: "saburo", score: 90},
5 {name: "noise"}, // スコアが無いノイズデータ
6];
7
8// reduceを使った合計得点の算出
9const scores = users
10 .filter(it => it.score)
11 .map(it => it.score);
12const add = (a, b) => a + b;
13const max = (a, b) => Math.max(a, b);
14console.log("max:", scores.reduce(max, 0)); // max: 100
15console.log("sum:", scores.reduce(add, 0)); // sum: 270
16console.log("avg:", scores.reduce(add, 0) / scores.length); // avg: 90
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/03/18 06:19