A cleaner way to accomplish this is by providing an initial value as the second argument to reduce:
Copyvar arr = [{x:1}, {x:2}, {x:4}];
var result = arr.reduce(function (acc, obj) { return acc + obj.x; }, 0);
console.log(result); // 7
Run code snippetEdit code snippet Hide Results Copy to answer Expand
The first time the anonymous function is called, it gets called with (0, {x: 1}) and returns 0 + 1 = 1. The next time, it gets called with (1, {x: 2}) and returns 1 + 2 = 3. It's then called with (3, {x: 4}), finally returning 7.
This also handles the case where the array is empty, returning 0.
javascript - How to call reduce on an array of objects to sum their properties? - Stack Overflow
How to use the JavaScript Array.prototype.reduce() - JavaScript Reduce Explained with Examples
Learning array.reduce() method, i need some help to understand it.
javascript - What does the Array method `reduce` do? - Stack Overflow
Videos
I own searched online but I do not understandthings like accumalator or reducer, I understand .map and .filter but not .reduce. If you could an analogy would be appreciated.
A cleaner way to accomplish this is by providing an initial value as the second argument to reduce:
Copyvar arr = [{x:1}, {x:2}, {x:4}];
var result = arr.reduce(function (acc, obj) { return acc + obj.x; }, 0);
console.log(result); // 7
Run code snippetEdit code snippet Hide Results Copy to answer Expand
The first time the anonymous function is called, it gets called with (0, {x: 1}) and returns 0 + 1 = 1. The next time, it gets called with (1, {x: 2}) and returns 1 + 2 = 3. It's then called with (3, {x: 4}), finally returning 7.
This also handles the case where the array is empty, returning 0.
After the first iteration your're returning a number and then trying to get property x of it to add to the next object which is undefined and maths involving undefined results in NaN.
try returning an object contain an x property with the sum of the x properties of the parameters:
Copyvar 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}
Explanation added from comments:
The return value of each iteration of [].reduce used as the a variable in the next iteration.
Iteration 1: a = {x:1}, b = {x:2}, {x: 3} assigned to a in Iteration 2
Iteration 2: a = {x:3}, b = {x:4}.
The problem with your example is that you're returning a number literal.
Copyfunction (a, b) {
return a.x + b.x; // returns number literal
}
Iteration 1: a = {x:1}, b = {x:2}, // returns 3 as a in next iteration
Iteration 2: a = 3, b = {x:2} returns NaN
A number literal 3 does not (typically) have a property called x so it's undefined and undefined + b.x returns NaN and NaN + <anything> is always 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.
Taken from here, arr.reduce() will reduce the array to a value, specified by the callback. In your case, it will basically sum the elements of the array.
Steps:
- Call function on 0,1 ( 0 is the initial value passed to
.reduce()as the second argument. Return sum od 0 and 1, which is 1. - Call function on previous result ( which is 1 ) and next array element. This returns sum of 1 and 2, which is 3
- Repeat until last element, which will sum up to 21
reduce() method has two parameters: a callback function that is called for every element in the array and an initial value.
The callback function also has two parameters: an accumulator value and the current value.
The flow for your array ([1, 2, 3, 4, 5, 6]) is like this:
1. return 0 + 1 // 0 is the accumulator which the first time takes the initial value, 1 is the current value. The result of this becomes the accumulator for the next call, and so on..
2. return 1 + 2 // 1 - accumulator, 2 - current value
3. return 3 + 3 // 3 - accumulator, 3 - current value, etc...
4. return 6 + 4
5. return 10 + 5
6. return 15 + 6
And when reached to the end of the array, return the accumulator, which here is 21
You're very close. One thing I noticed is that you swapped the parameters to the .reduce() callback. It goes accumulator (aka total) then current value, you had it flipped. Also, the current value is the actual object of that iteration, so you can access the totalDonation property just like normal with .totalDonation. Lastly, you just need an initial value for the reduce function. This is because .reduce() takes 2 paramters - first it takes a callback function (which you have), and the second parameter is an initial value which will be used as the accumulator value for the first iteration of the loop. Since we are doing a sum, it makes sense to start with 0, hence why we pass 0 in as the initial value to reduce.
Copyconst box=document.querySelector(".wholeBox");
let contribution=[
{name:"charles",
totalDonation:1000},
{name:"oliver",
totalDonation:500},
{name:"leo",
totalDonation:300},
];
// reduce takes 2 parameters - a callback and an initial value. We provide the callback function
// and 0 as the initial value of the accumulator so we can start from 0 when summing the totals
const totalContribution=contribution.reduce((totalValue, currValue) => {
// currValue will be the actual object ( i.e. {name: "charles", "totalDonation": 1000} )
return totalValue + currValue.totalDonation;
}, 0); // <--- Here is where we provide the initial value for `.reduce()`
box.innerHTML=totalContribution;
Copy<div class="wholeBox"></div>
Run code snippetEdit code snippet Hide Results Copy to answer Expand
here's how u can do it:
Copylet contribution=[
{name:"charles",
totalDonation:1000},
{name:"oliver",
totalDonation:500},
{name:"leo",
totalDonation:300},
];
const totalDonations = contribution.reduce((sum, curr) => {
return curr.totalDonation + sum;
}, 0)
console.log(totalDonations)
Run code snippetEdit code snippet Hide Results Copy to answer Expand
in your attempt, you didn't reduce by the specific param that you want to sum upon