JavaScriptのReduce()関数の利点は何ですか? (およびmap())
-
28-10-2019 - |
質問
このようなものを書く必要がある関数のために、JavaScriptでresid()メソッドを使用するかどうかを決定しようとしています
var x = [some array], y = {};
for (...) {
someOperation(x[i]);
y[x[i]] = "some other value";
}
これで、これは明らかに次の方法でreduce()関数として記述できます。
x.reduce(function(prev, current, index, arr) {
someOperation(current);
prev[current] = "some other value";
return prev;
}, {})
またはそのようなもの。 2つの間にパフォーマンスやその他の違いはありますか?または、他の理由(たとえば、ブラウザのサポートなど)がWebプログラミング環境で他のものよりも好まれるべきですか?ありがとう。
解決
私はこれらの操作(削減、マップ、フィルターなど)を好みますが、それでもそれらを使用することは不可能です 特定 実装でそれらをサポートしていないブラウザ。確かに、あなたは拡張することによってそれを「パッチ」することができます Array
プロトタイプですが、それはワームの缶も開いています。
これらの機能には本質的に間違っていることはないと思います。そして、それらはより良いコードを作ると思いますが、今のところはそれらを使用しないことが最善です。人口の割合が高いと、これらの機能をサポートするブラウザを使用すると、公正なゲームになると思います。
パフォーマンスに関する限り、これらはおそらく、関数呼び出しからのオーバーヘッドのために、ループ用に手書きの手で書かれているよりも遅くなるでしょう。
他のヒント
map
と filter
と reduce
と forEach
そして...(詳細: https://developer.mozilla.org/en/javascript/reference/global_objects/array#iteration_methods )通常のループよりもはるかに優れています。
- 彼らはよりエレガントです
- 彼らは機能的なプログラミングを奨励しています(機能プログラミングの利点を参照)
- 関数を書く必要があります とりあえず パラメーターとして、反復変数としてそれらに渡します。これは、JavaScriptにブロックスコープがないためです。のような関数
map
とreduce
彼らはあなたの反復変数を自動的にセットアップし、それをあなたのためにあなたの機能に渡すので、あなたの仕事を非常に簡単にします。
IE9はこれらをサポートすると主張しています。彼らは公式のJavaScript/EcMascript仕様にあります。 IE8を使用している人を気にかけている場合、それはあなたの特権です。あなたが本当に気にかけているなら、あなたはそれをオーバーライドすることでそれをハックすることができます Array.prototype
IE8以上の場合、IE8以降を「修正」します。
Reduceは、以前の要素の結果を順次処理した結果として、配列から1つの値を返すために使用されます。
Reducerightは同じことをしますが、最後から始まり、逆方向に動作します。
マップは、メンバーがすべて関数を通過した配列を返すために使用されます。
どちらの方法も配列自体に影響しません。
var a1 = ['1'、 '2'、 '3'、 '4'、 '5'、 '6'、 '7'、 '8'];
//このマップの使用は、番号に変換された元の要素の新しい配列を返します -
a1 = a1.map(number); // >> a1の各要素が数に変換されました
//これにより、合計アレイ要素が減少します -
var a1sum = a1.reduce(function(a、b){return a+b;});
// a1sum >>返された値:(number)36
古いブラウザではサポートされていないため、代替品を提供する必要があります。あなたがしているすべてが単純なループで複製できるならば、それだけの価値はありません。
母集団の標準偏差を把握することは、マップと削減の両方を効果的に使用できる例です。
Math.mean= function(array){
return array.reduce(function(a, b){ return a+b; })/array.length;
}
Math.stDeviation=function(array){
var mean= Math.mean(array);
dev= array.map(function(itm){return (itm-mean)*(itm-mean); });
return Math.sqrt(dev.reduce(function(a, b){ return a+b; })/array.length);
}
var A2= [6.2, 5, 4.5, 6, 6, 6.9, 6.4, 7.5];
alert ('mean: '+Math.mean(A2)+'; deviation: '+Math.stDeviation(A2))
Kennebec-いいですが、あなたの stdeviation 関数呼び出し 減らす 2回と 地図 一度に1回の呼び出しが必要な場合 減らす (これによりはるかに速くなります):
Math.stDev = function (a) {
var n = a.length;
var v = a.reduce(function (v, x) {
v[0] += x * x;
v[1] += x;
return v;
}, [0,0]);
return Math.sqrt( (v[0] - v[1]*v[1] / n) / n );
}
割り当てるときは、数値に変換を行う必要があります V [1 文字列番号が結果を台無しにしないことを確認するために、最後の行の除数はほとんどの場合(n -1)でなければなりませんが、それはOP次第です。 :-)