Reputation: 523
I have an array of JSON object as follows
var array = [{"id":"1","value": "13"},{"id":"2","value": "23"},{"id":"1","value": "33"},{"id":"3","value": "13"}]
Then I grouped the json array according to the id as follows
var groupArray = {"1":[{"id":"1","value": "13"},{"id":"1","value": "33"}],
"2": [{"id":"2","value": "23"}],
"3": [{"id":"3","value": "13"}]};
I want to iterate through groupArray and get the total of value for each id where duplicate ids should sum up together and give one single total value and assign them into another array as follows
resultArray
[{"id":"1","value":"46"},{"id":"2","value":"23"},{"id":"3","value":"13"}]
This should be achieved using angularjs
Upvotes: 2
Views: 3627
Reputation: 33726
You can use the function reduce
for grouping and the function Object.values
for extracting the desired output.
var array = [{"id":"1","value": "13"},{"id":"2","value": "23"},{"id":"1","value": "33"},{"id":"3","value": "13"}]
let result = Object.values(array.reduce((a, {id, value}) => {
(a[id] || (a[id] = {id, value: 0})).value += +value;
return a;
}, Object.create(null)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 6728
Use Object.entries
to get the object keys and values as an array then iterate through the values in order to sum up the value
inside each object and then push it with its id
to resultArray
.
let groupArray = {"1":[{"id":"1","value": "13"},{"id":"1","value": "33"}],"2": [{"id":"2","value": "23"}],"3": [{"id":"3","value": "13"}]}
let resultArray = []
Object.entries(groupArray).forEach(g => {
let sumValue = 0
g[1].forEach(o => sumValue += parseFloat(o.value))
resultArray.push({
"id": g[0],
"value": sumValue.toString()
})
})
console.log(resultArray)
Upvotes: 0
Reputation: 92440
It would be easier if groupArray
was in fact an array. As an object you have to be aware that order has not always been guaranteed, but it's not clear if the order of your final array is important. In recent JS it shouldn't matter — numeric keys will be sorted. You can just call map()
on the Object.values()
, then use reduce()
on each array:
var groupArray = {
"1":[{"id":"1","value": "13"},{"id":"1","value": "33"}],
"2": [{"id":"2","value": "23"}],
"3": [{"id":"3","value": "13"}]
}
let sums = Object.values(groupArray)
.map(arr => arr.reduce((sums,{id, value}) => ({id, value: sums.value + +value}), {value:0}))
console.log(sums)
You need to be aware that value
is a string and make sure you are adding numbers not concatenating strings when you use +
.
Upvotes: 1
Reputation: 56
This will work
const object = {}
const array = [{"id":"1","value": "13"},{"id":"2","value": "23"},{"id":"1","value": "33"},{"id":"3","value": "13"}]
array.forEach(data => {
object[data.id] = parseInt(data.value, 10) + (object[data.id] || 0)
})
const result = Object.entries(object).map(data => {
return {
'id': data[0],
'value': data[1]
}
})
console.log(result)
Upvotes: 0