说我想对a.x
中的每个元素求和arr
。
arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a.x + b.x})
>> NaN
我有理由相信斧头在某些时候是不确定的。
以下工作正常
arr = [1,2,4]
arr.reduce(function(a,b){return a + b})
>> 7
我在第一个示例中做错了什么?
说我想对a.x
中的每个元素求和arr
。
arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a.x + b.x})
>> NaN
我有理由相信斧头在某些时候是不确定的。
以下工作正常
arr = [1,2,4]
arr.reduce(function(a,b){return a + b})
>> 7
我在第一个示例中做错了什么?
返回所有x
道具的总和:
arr.reduce(
(a,b) => (a.x || a) + b.x
)
减少功能迭代集合
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.
);
在每个索引回调期间,将变量“累加器”的值传递到回调函数中的“ a”参数中。如果我们不初始化“累加器”,则其值将是不确定的。调用undefined.x会给您错误。
要解决此问题,请使用上面显示的Casey答案将值0初始化为“累加器” 。
为了了解“ reduce”功能的内在,我建议您看一下该功能的源代码。Lodash库具有reduce函数,其功能与ES6中的reduce函数完全相同。
这里是链接: 减少源代码
第一步,它将正常工作,因为will的值为a
1 ,will 的值为b
2,但是由于将返回2 + 1,而在下一步中,of的值b
将是返回值from step 1 i.e 3
,因此b.x
将是不确定的。 .and undefined + anyNumber将为NaN,这就是为什么要得到该结果的原因。
arr.reduce(function(a,b){return a + b.x},0);
如果您有一个包含大量数据的复杂对象(如对象数组),则可以采用逐步的方法来解决此问题。
例如:
const myArray = [{ id: 1, value: 10}, { id: 2, value: 20}];
首先,您应该将数组映射到您感兴趣的新数组,在此示例中,它可能是新的值数组。
const values = myArray.map(obj => obj.value);
此回调函数将返回一个仅包含原始数组中值的新数组,并将其存储在值const上。现在,您的值const是一个像这样的数组:
values = [10, 20];
现在,您可以执行还原了:
const sum = values.reduce((accumulator, currentValue) => { return accumulator + currentValue; } , 0);
如您所见,reduce方法多次执行回调函数。对于每次,它都会获取数组中该项的当前值,并与累加器求和。因此,要正确求和,需要将累加器的初始值设置为reduce方法的第二个参数。
现在您有了新的const和,其值为30。
在减少的每一步中,您都不会返回新{x:???}
对象。因此,您需要执行以下操作:
arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a + b.x})
或者你需要做
arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return {x: a.x + b.x}; })
其他人回答了这个问题,但我想我会采用另一种方法。您可以直接映射(从ax到x)并缩小(添加x),而不是直接求和ax。
arr = [{x:1},{x:2},{x:4}]
arr.map(function(a) {return a.x;})
.reduce(function(a,b) {return a + b;});
诚然,它可能会稍慢一些,但我认为值得一提。
第一次迭代后,您将返回一个数字,然后尝试获取该数字的属性x
以将其添加到下一个对象中,该对象是undefined
和数学,涉及到undefined
结果NaN
。
尝试返回一个对象x
,该对象包含一个属性,该属性与参数的x个属性之和:
var arr = [{x:1},{x:2},{x:4}];
arr.reduce(function (a, b) {
return {x: a.x + b.x}; // returns object with property x
})
// ES6
arr.reduce((a, b) => ({x: a.x + b.x}));
// -> {x: 7}
从注释中添加了说明:
每次迭代的返回值[].reduce
用作a
下一次迭代的变量。
迭代1: ,,a = {x:1}
分配给在迭代2b = {x:2}
{x: 3}
a
迭代2:a = {x:3}
,b = {x:4}
。
您的示例的问题在于您要返回数字文字。
function (a, b) {
return a.x + b.x; // returns number literal
}
迭代1: ,,a = {x:1}
如在下次迭代b = {x:2}
// returns 3
a
迭代2 :a = 3
,b = {x:2}
返回NaN
许多文字3
不(通常)有一个叫做财产x
所以它undefined
和 undefined + b.x
回报NaN
,并NaN + <anything>
始终NaN
Clarification: I prefer my method over the other top answer in this thread as I disagree with the idea that passing an optional parameter to reduce with a magic number to get out a number primitive is cleaner. It may result in fewer lines written but imo it is less readable.
一种更清洁的方法是通过提供一个初始值:
var arr = [{x:1}, {x:2}, {x:4}];
arr.reduce(function (acc, obj) { return acc + obj.x; }, 0); // 7
console.log(arr);
第一次调用匿名函数时,将使用调用(0, {x: 1})
并返回0 + 1 = 1
。下次,它被调用(1, {x: 2})
并返回1 + 2 = 3
。然后调用(3, {x: 4})
,最后返回7
。
您不应该将ax用作累加器,而是可以像`arr = [{x:1},{x:2},{x:4}]这样操作
arr.reduce(function(a,b){a + bx},0)`