假设我想对arr中的每个元素求和。
arr = [ { x: 1 }, { x: 2 }, { x: 4 } ];
arr.reduce(function(a, b){ return a.x + b.x; }); // => NaN
我有理由相信a。x在某些时候是没有定义的。
以下工作正常
arr = [ 1, 2, 4 ];
arr.reduce(function(a, b){ return a + b; }); // => 7
第一个例子中我做错了什么?
假设我想对arr中的每个元素求和。
arr = [ { x: 1 }, { x: 2 }, { x: 4 } ];
arr.reduce(function(a, b){ return a.x + b.x; }); // => NaN
我有理由相信a。x在某些时候是没有定义的。
以下工作正常
arr = [ 1, 2, 4 ];
arr.reduce(function(a, b){ return a + b; }); // => 7
第一个例子中我做错了什么?
当前回答
var arr = [{x:1}, {x:2}, {x:3}];
arr.map(function(a) {return a.x;})
.reduce(function(a, b) {return a + b});
console.log(arr);
//I tried using the following code and the result is the data array
//result = [{x:1}, {x:2}, {x:3}];
var arr2 = [{x:1}, {x:2}, {x:3}]
.reduce((total, thing) => total + thing.x, 0);
console.log(arr2);
// and I changed the code to like this and it worked.
// result = 6
其他回答
你不应该使用a.x作为累加器,相反,你可以这样做 ' arr = [{x:1},{x:2},{x:4}]
Arr.reduce(函数(a,b){a + b.x},0) '
我在ES6中做了一点改进:
arr.reduce((a, b) => ({x: a.x + b.x})).x
返回数
我们可以使用数组减少方法来创建新的对象,我们可以使用这个选项来求和或过滤
const FRUITS = ["apple", "orange"] const fruitBasket ={香蕉:{数量:10,kg:3},苹果:{数量:30,kg:10},橙子:{数量:1,kg:3}} const newFruitBasket =水果。Reduce ((acc, fruit) =>({…acc, [fruit]: fruitBasket[fruit]}), {}) console.log (newFruitBasket)
Reduce函数在集合上迭代
arr = [{x:1},{x:2},{x:4}] // is a collection
arr.reduce(function(a,b){return a.x + b.x})
翻译:
arr.reduce(
//for each index in the collection, this callback function is called
function (
a, //a = accumulator ,during each callback , value of accumulator is
passed inside the variable "a"
b, //currentValue , for ex currentValue is {x:1} in 1st callback
currentIndex,
array
) {
return a.x + b.x;
},
accumulator // this is returned at the end of arr.reduce call
//accumulator = returned value i.e return a.x + b.x in each callback.
);
在每次索引回调期间,变量accumulator的值为 在回调函数中传入"a"参数。如果不初始化"accumulator",它的值将是undefined。调用定义。X会给出误差。 要解决这个问题,初始化“accumulator”,值为0,如Casey的答案所示。
为了理解“reduce”函数的输入输出,我建议您查看该函数的源代码。 Lodash库有reduce函数,它的工作原理与ES6中的“reduce”函数完全相同。
以下是链接: 减少源代码
为了将所指出的内容形式化,reducer是一种变形,它接受两个可能碰巧是同一类型的参数,并返回与第一个参数匹配的类型。
function reducer (accumulator: X, currentValue: Y): X { }
这意味着减速器的主体需要将currentValue和累加器的当前值转换为新累加器的值。
这在添加时以一种简单的方式工作,因为累加器和元素值恰好是同一类型(但用途不同)。
[1, 2, 3].reduce((x, y) => x + y);
因为它们都是数字。
[{ age: 5 }, { age: 2 }, { age: 8 }]
.reduce((total, thing) => total + thing.age, 0);
现在我们给聚合器一个起始值。在绝大多数情况下,起始值应该是您期望聚合器的类型(您期望作为最终值出现的类型)。 虽然你没有被强迫这样做(也不应该这样做),但记住这一点很重要。
一旦你知道了这一点,你就可以为其他n:1的关系问题写出有意义的约简。
去掉重复的单词:
const skipIfAlreadyFound = (words, word) => words.includes(word)
? words
: words.concat(word);
const deduplicatedWords = aBunchOfWords.reduce(skipIfAlreadyFound, []);
提供所找到的所有单词的计数:
const incrementWordCount = (counts, word) => {
counts[word] = (counts[word] || 0) + 1;
return counts;
};
const wordCounts = words.reduce(incrementWordCount, { });
将数组的数组缩减为单个平面数组:
const concat = (a, b) => a.concat(b);
const numbers = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
].reduce(concat, []);
任何时候,当您希望从一个数组转换到一个不匹配1:1的值时,都可以考虑reduce。
事实上,map和filter都可以实现为约简:
const map = (transform, array) =>
array.reduce((list, el) => list.concat(transform(el)), []);
const filter = (predicate, array) => array.reduce(
(list, el) => predicate(el) ? list.concat(el) : list,
[]
);
我希望这为如何使用reduce提供了进一步的背景知识。
另外,我还没有详细说明的是,当期望输入和输出类型是动态的时,因为数组元素是函数:
const compose = (...fns) => x =>
fns.reduceRight((x, f) => f(x), x);
const hgfx = h(g(f(x)));
const hgf = compose(h, g, f);
const hgfy = hgf(y);
const hgfz = hgf(z);