I have a json array with Id and age as follows
var arrayVal = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: "20"},{id:"3", age: 20},{id:"5", age: 10}];
I want to get sum of age which belong to same id which will be as follows
1 = 20
2 = 50
3 = 20
5 = 10
Please find the below code
$scope.TestFunc = function()
{
var tot = 0;
var arrayVal = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: "20"},{id:"3", age: 20},{id:"5", age: 10}];
for(var i=0; i <arrayVal.length; i++ )
{
for(var j=1; j<arrayVal.length - i; j++ )
{
if(arrayVal[i].id == arrayVal[j].id)
{
tot = arrayVal[i].age.valueOf() + arrayVal[j].age.valueOf();
}
else{
tot = tot + arrayVal[i].age;
}
}
}
console.log("-----total----"+tot);
}
I don't receive the expected output. the console shows the output as 202020. What has gone wrong in the above code?
I have a json array with Id and age as follows
var arrayVal = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: "20"},{id:"3", age: 20},{id:"5", age: 10}];
I want to get sum of age which belong to same id which will be as follows
1 = 20
2 = 50
3 = 20
5 = 10
Please find the below code
$scope.TestFunc = function()
{
var tot = 0;
var arrayVal = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: "20"},{id:"3", age: 20},{id:"5", age: 10}];
for(var i=0; i <arrayVal.length; i++ )
{
for(var j=1; j<arrayVal.length - i; j++ )
{
if(arrayVal[i].id == arrayVal[j].id)
{
tot = arrayVal[i].age.valueOf() + arrayVal[j].age.valueOf();
}
else{
tot = tot + arrayVal[i].age;
}
}
}
console.log("-----total----"+tot);
}
I don't receive the expected output. the console shows the output as 202020. What has gone wrong in the above code?
Share Improve this question edited Jun 11, 2019 at 3:38 Robby Cornelissen 97.5k23 gold badges149 silver badges175 bronze badges asked Jun 11, 2019 at 3:24 tharindutharindu 5236 silver badges28 bronze badges 1- I've rolled back your edit. Please don't invalidate your question after it has been answered by fixing the code in the question. – Robby Cornelissen Commented Jun 11, 2019 at 3:39
3 Answers
Reset to default 8With a simple reduce()
operation:
const array = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: "20"},{id:"3", age: 20},{id:"5", age: 10}];
const ages = array.reduce((a, {id, age}) => (a[id] = (a[id] || 0) + +age, a), {});
console.log(ages);
Besides the reduce
solution being more pact and declarative, the main problem with the code provided is due to coercion. One of the age
values has the string "20"
, forcing the subsequent +
operations to be interpreted as string concatenation.
This answer avoids this unexpected side-effect using the +age
, forcing age
to be a Number
(this could be made explicit by doing Number(age)
instead).
The age must be number. It should not be as a string. In your code, id:2 has 20 as string. Kindly check with datatype in arrayVal.
var arrayVal = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: 20},{id:"3", age: 20},{id:"5", age: 10}];
$scope.TestFunc = function()
{
var tot = 0;
var arrayVal = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: 20},{id:"3", age: 20},{id:"5", age: 10}];
for(var i=0; i <arrayVal.length; i++ )
{
for(var j=1; j<arrayVal.length - i; j++ )
{
if(arrayVal[i].id == arrayVal[j].id)
{
tot = arrayVal[i].age.valueOf() + arrayVal[j].age.valueOf();
}
else{
tot = tot + arrayVal[i].age;
}
}
}
console.log("-----total----"+tot);
}
I've prepared another answer using Array#reduce method which returns array of objects instead of simple array:
const arrayVal = [{id:"1", age: 20},{id:"2", age: 30},{id:"2", age: "20"},{id:"3", age: 20},{id:"5", age: 10}];
let summedAges = arrayVal.reduce((a, c) => {
let filtered = a.filter(el => el.id === c.id);
if(filtered.length > 0){
a[a.indexOf(filtered[0])].age += +c.age;
}else{
a.push(c);
}
return a;
}, []);
console.log(JSON.stringify(summedAges));