How to Call Reduce on an Array of Objects to Sum Their Properties

How to call reduce on an array of objects to sum their properties?

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:

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}

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.

function (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.

Reduce and sum array of objects (JS)

You can use Array.reduce():

var models = [    { id: 1, name: "samsung", seller_id: 1, count: 56 },    { id: 1, name: "samsung", seller_id: 2, count: 68 },    { id: 2, name: "nokia", seller_id: 2, count: 45 },    { id: 2, name: "nokia", seller_id: 3, count: 49 }];
var arr = models.reduce((acc, item) => { let existItem = acc.find(({id}) => item.id === id); if(existItem) { existItem.count += item.count; } else { acc.push(item); } return acc;}, []);
console.log(arr);

sum all values of an object in an array of objects javascript

Use Array.reduce to calculate the sum

const sum = array.reduce((acc, o) => acc + parseInt(o.value), 0)

Reduce multiple properties in array of array of objects and omit other properties using Ramda

One Ramda approach:

const convert = pipe (
transpose,
map (xs => ({
index: xs [0] .index,
value: xs .reduce ((a, {value}) => a + Number (value), 0),
participants: sum (pluck ('participants') (xs))
}))
)

const data = [[{index: 320, blocks: 2, value: "31011784785", participants: 1222, cost: "1286828506"}, {index: 319, blocks: 0, value: "111306385", participants: 18, cost: "0"}, {index: 318, blocks: 0, value: "14550473", participants: 10, cost: "0"}], [{index: 320, blocks: 1, value: "7089001673", participants: 492, cost: "648196615"}, {index: 319, blocks: 0, value: "13551137", participants: 8, cost: "0"}, {index: 318, blocks: 0, value: "11499815", participants: 5, cost: "0"}], [{index: 320, blocks: 1, value: "408900161", participants: 200, cost: "648196615"}, {index: 319, blocks: 0, value: "23551231", participants: 10, cost: "0"}, {index: 318, blocks: 0, value: "104324219", participants: 5, cost: "0"}]]

console .log (convert (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {pipe, transpose, map, sum, pluck, reduce, applySpec} = R </script>

Trying to apply filter and reduce on an array to sum only numbers

The first argument in a reduce callback is the "accumulator" - something that takes the initial value and is then passed into each iteration. The second value is the item that's next in the iteration whether that's a number, a string, an object etc.

In your example you're iterating over an array of objects, so you must perform the sum operation using the age value of each of those objects.

const arr = [
{ name: 'Clarie', age: 22 },
{ name: 'Bobby', age: 30 },
{ name: 'Antonio', age: 40 }
];

const total = arr.reduce((acc, obj) => {
return acc + obj.age;
}, 0);

console.log(total);

How do I organize an Array of objects according to the sum of its attributes?

You're trying to do two things here.

  1. Find the total sales for each seller.
  2. Sort the total sales for each seller.

Inside my sort function you can see I am filtering all of the sales by the seller.

Once I have just the sales for one seller I use the reduce method to sum the quantity of their sales into an easy to use number.

Then I'm comparing the previous sellers quantity to the current sellers quantity to re-order them using the sort method.

I encourage you to read the documentation of the methods used so you understand what is happening at each step.

Methods used:
Sort
Filter
Reduce

const sellers = [{
id: 1,
name: 'juan',
age: 23
}, {
id: 2,
name: 'adrian',
age: 32
}, {
id: 3,
name: 'apolo',
age: 45
}];

const sales = [{
equipo: 'frances',
sellerId: 2,
quantity: 234
}, {
equipo: 'italiano',
sellerId: 3,
quantity: 24
}, {
equipo: 'polaco',
sellerId: 1,
quantity: 534
}, {
equipo: 'frances',
sellerId: 2,
quantity: 1234
}, {
equipo: 'frances',
sellerId: 3,
quantity: 2342
}];

const expected = [{
id: 3,
name: 'apolo',
age: 45
}, {
id: 2,
name: 'adrian',
age: 32
}, {
id: 1,
name: 'juan',
age: 23
}]

const result = sellers.sort((a, b) => {
totalA = sales.filter(sale => sale.sellerId === a.id).reduce((acc, val) => acc + val.quantity, 0)
totalB = sales.filter(sale => sale.sellerId === b.id).reduce((acc, val) => acc + val.quantity, 0)
return totalB - totalA
})

// Check we get what we expect
console.log(JSON.stringify(expected) === JSON.stringify(result))

Sum of fields in an array of objects with reduce returns NaN

When using Array.reduce(), if you don't state an initial value, the 1st item of the array becomes the initial value. Since you want a number, and not an object as the result, initialize with 0. Since the accumulator is now a number, and not an object, use accumulator instead of accumulator.a in the function's body:

const array = [{a:1}, {a:2}, {a:3}];const reducer = (accumulator, currentValue) => accumulator + currentValue.a;console.log(array.reduce(reducer, 0));

how to use reduce method on an array of object having mix data types?

The reduce method accepts a third second argument that will be used as the initial value for your computation.
As we're looking to calculate a sum, then setting 0 as the initial value is a good choice.

const details = [{
name: "smith",
age: 29,
amount: 100
},
{
name: "Aero",
age: 24,
amount: 180
},
],
/**
* a: is the returned value from the last iteration, initially starts with an empty object "{}".
* c: is the current VALUE from "details" array.
*/
totalAmount = details.reduce((a, c) => a + c.amount, 0);

// prints "totalAmount" value
console.log(totalAmount); // prints: 280

Using reduce array method to sum up (increment) records properties results with an undefined error

I saw your code, and you should return the acc in the reduce. I created another solution version and incremented the corresponding color counter based on the preferredColor value. You can check it out here:

const myRecords = [
{ name: "john", preferredColor: "green" },
{ name: "diana", preferredColor: "red" },
{ name: "george", preferredColor: "yellow" },
{ name: "ron", preferredColor: "green" },
{ name: "sarah", preferredColor: "red" },
{ name: "rachel", preferredColor: "red" },
{ name: "nicole", preferredColor: "yellow" },
{ name: "chris", preferredColor: "red" },
];

const result = myRecords.reduce((prev, curr) => ({
...prev,
colorCount: {
...prev.colorCount,
[curr.preferredColor]: prev.colorCount[curr.preferredColor] + 1
}
}), { colorCount: { red: 0, yellow: 0, green: 0 } })

console.log(result)


Related Topics



Leave a reply



Submit