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.
- Find the total sales for each seller.
- 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
Settimeout and "This" in JavaScript
How to Append <Script></Script> in JavaScript
How to Use Multiple Refs for an Array of Elements with Hooks
What Is "Undefined X 1" in JavaScript
Prevent Scroll Bubbling from Element to Window
How to Format/Tidy/Beautify in JavaScript
How to Solve Uncaught Rangeerror When Download Large Size JSON
Text Wrap in a <Canvas> Element
Syntax Highlighting Code with JavaScript
How to Add Custom HTML Attributes in Jsx
Why Can't I Add Properties to a String Object in JavaScript
How Might I Find the Largest Number Contained in a JavaScript Array
Foreach on Queryselectorall Not Working in Recent Microsoft Browsers
How to Sort Elements by Numerical Value of Data Attribute
Jquery $("#Radiobutton").Change(...) Not Firing During De-Selection