コードを見ると、考えられる答えは1つだけです。関数counter
はに渡されたときに一度だけ参照されるためreduce()
、reduceは関数に引数を提供する必要があります。
削減の仕組み
これは、reduceがどのように機能するかを視覚化したものです。ダイアグロムを上から下に読み、/
どのパラメーター(下)が上の関数\
に渡されるかを示す必要があります。counter()
return value of reduce()
/
etc ...
/
counter
/ \
counter xs[2]
/ \
counter xs[1]
/ \
0 xs[0]
counter()
最初に0
(結局のところ、要素をまだ処理していないときに見られるゼロの初期の合計量はちょうどゼロです)、最初の要素が提供されます。
0
配列の最初の要素がゼロの場合、これは1ずつ増加します。最初の要素を見た後の新しい合計はcounter(0, xs[0])
、reduce()
関数に返されます。要素が残っている限り、この値を新しい保留中の合計としてcounter()
、配列の次の要素とともに関数に渡しますxs[1]
。
配列に要素がある限り、このプロセスが繰り返されます。
この概念をコードにマッピングする
function reduce(combine, base, array) {
forEach(array, function (element) {
base = combine(base, element);
});
return base;
}
図からわかるように、は、構造内の最初の「反復」を示すとともに、最初に関数に0
渡されます。結果の値は、に書き戻されます。base
element
xs[0]
forEach
base
視覚化でわかるように、0
は関数の左パラメーターでcounter()
あり、その結果は左パラメーターとしてに渡されますcounter()
。base/total
コンストラクト内で左側のパラメーターとして機能するためforEach
、その値をに書き戻すのは理にかなっています。base/total
そのため、前の結果はcounter()/combine()
次の反復で再び渡されます。sのパス/
は、の「フロー」ですbase/total
。
どこelement
から来たの
Eloquent JavaScriptの第6章から、次の実装がありますforEach()
(コメントでは、への呼び出しをaction
最終的な値に置き換えました)。
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]); // <-- READ AS: base = counter(base, array[i]);
}
action
for
を繰り返しながら、すべての要素の単純なループ内で呼び出される関数を示しますarray
。
あなたの場合、これは次のように渡されaction
ますforEach()
:
function (element) {
base = combine(base, element);
}
これは、への各呼び出しで定義された匿名関数reduce()
です。したがって、の反復ごとにelement
「本当に」 1回です。array[i]
for