reduce には、結合関数ではなく無名関数が渡されていることがわかります
それは本当ではありません。無名関数はcombine
関数です。
combine(base, element)
対function(total, element)
これら 2 つの関数呼び出しは本質的に互いに同等です: 結合 (ベース、要素) と関数 (合計、要素)?
いいえ、それらはまったく別のものです。
前者は、 によって参照される関数への関数呼び出しcombine
です。
ただし、2 番目は新しい関数値に評価されます。の場合:
reduce(function(total, element) {...}, ...);
reduce()
には関数値が渡されます。これが意味することは、新しい関数が作成さtotal
れるということです。これは、2 つのパラメーター (とで示されます) を受け入れる関数ですelement
。この関数は に渡されreduce
ます。
昨日のビジュアライゼーションをリサイクルさせてください。これはあなたのケースだけに当てはまるのではなく、 reduce(left)コンセプトのすべての実施形態に当てはまることを認識することが重要です。
return value of reduce()
/
etc ...
/
combine
/ \
combine xs[2]
/ \
combine xs[1]
/ \
0 xs[0]
もちろん、これは何が起こるかを示すだけであり、どのようにではなく、あなたの場合はどのように求めていると思います。この視覚化を念頭に置いて、結果がどうなるかを確認してください。
関数の代用
何が起こっているのかをより明確にするために、渡されている関数を徐々に置き換えます。
プログラムの開始:
function countZeroes(array) {
return count(equals(0), array);
}
equals(0)
(これを一種のカリー化と呼ぶことができます) は関数に評価され、 に渡されcount()
ます。
これにより、基本的に次のcount()
関数が得られます。
function count(array) {
return reduce(function(total, element) { // Where is the value for total coming from?
return total + (0 == element ? 1 : 0);
}, 0, array);
}
ここから、combine
引数を抽出できます。
function combine(total, element) { // Where is the value for total coming from?
return total + (0 == element ? 1 : 0);
}
これは、reduce 関数内で使用される関数です。
function reduce(base = 0, array) {
forEach(array, function (element) {
base = combine(base, element);
});
return base;
}
reduce(0, array)
関数から呼び出されcount()
ます。に渡される関数はforEach
、 の実装を考慮して、次のように書き直すことができますcombine
。
function reduce(base = 0, array) {
forEach(array, function (element) {
base = base + (0 == element ? 1 : 0);
});
return base;
}
base
を表すことに注意してくださいtotal
。
最後のステップとして、何をするかを考慮forEach()
します。
function reduce(base = 0, array) {
for (var i = 0; i < array.length; i++)
base = base + (0 == array[i] ? 1 : 0);
}
return base;
}
したがって、これはcount()
本質的に次のようになります。すべての呼び出しがラップされていません。
function count(array) {
var base = 0;
for (var i = 0; i < array.length; i++)
base = base + (0 == array[i] ? 1 : 0);
}
return base;
}