第1引数「配列(Object)」の前の値をメモ化して現在のindexの値と共に第2引数の関数に渡し各値を処理。累積処理される。
■使用例
var arr = [ 1 , 2 , 3 ];
var func = function(memo, value){
return memo + value;
}
// re = 6
var re = _.reduce( arr, func );
■内部構造
_.reduce = _.foldl = _.inject = createReduce(1);
//「dir = 1」が適用された関数を返す。
function createReduce(dir) {
// 下の返される関数で最後に呼ばれる関数。
function iterator(obj, iteratee, memo, keys, index, length) {
// 配列(obj)のそれぞれの値を処理するforループ。
for (; index >= 0 && index < length; index += dir) {
var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
}
// 累積した結果を返す。
return memo;
}
// _.reduce()の引数はこの返される関数の引数。
return function(obj, iteratee, memo, context) {
// 引数 context がない場合は iteratee の関数がそのまま返る。
iteratee = optimizeCb(iteratee, context, 4);
// 引数 obj が Object なら key 値の配列を作成。
var keys = !isArrayLike(obj) && _.keys(obj),
// 引数 obj の length 抽出処理。
length = (keys || obj).length,
// _.reduce() は前から処理するため、index = 0。
index = dir > 0 ? 0 : length - 1;
// 引数が3未満なら 配列の最初の値をメモする。
if (arguments.length < 3) {
memo = obj[keys ? keys[index] : index];
index += dir;
}
return iterator(obj, iteratee, memo, keys, index, length);
};
}