# javascript calculation of person ages and heights

I need to take sum of all the person's ages and heights.

Input Array:

[
{
"personId": 1,
"ages": [
1,
4,
5
],
"heights": [
1,
1,
2
]
},
{
"personId": 2,
"ages": [
4,
2,
2
],
"heights": [
1,
4,
2
]
},
{
"personId": 2,
"ages": [
2,
1,
1
],
"heights": [
12
]
}
]


Desired Output:

[
{
"type": "ages",
"values": 22
},
{
"type": "heights",
"values": 23
}
]


My Solution (Which is working perfectly fine):

var agesTotal = 0;
var heightsTotal = 0;
var resultArr = [];

var sourceArr = [{personId: 1, ages: [1,4,5], heights: [1,1,2]}, {personId: 2, ages: [4,2,2], heights: [1,4,2]}, {personId: 2, ages: [2,1,1], heights: [12]}];

for(var i = 0; i < sourceArr.length; i++){

if(sourceArr[i].ages){

if(i == 0){

resultArr.push({
type: "ages",
values: agesTotal
});
}

for(var n = 0; n < resultArr.length; n++){

if(resultArr[n].type == "ages"){

resultArr[n].values += agesTotal + sourceArr[i].ages.reduce((partialSum, a) => parseFloat(partialSum) + parseFloat(a), 0)
}
}
}

if(sourceArr[i].heights){

if(i == 0){

resultArr.push({
type: "heights",
values: heightsTotal
});
}

for(var n = 0; n < resultArr.length; n++){

if(resultArr[n].type == "heights"){

resultArr[n].values += heightsTotal + sourceArr[i].heights.reduce((partialSum, a) => parseFloat(partialSum) + parseFloat(a), 0)
}
}
}
}


This above code of mine is producing the correct response, but it seems like so much processing and unoptimized.

What I need is the best & optimized possible solution for this operation

## 1 Answer

forEach and reduce remove all the effort of the loops, and patching up the output format.

You seem to deal with the possibility of ages or heights properties not existing in the input array, which adds some complexity to the reduce call. As written in the snippet, it deals with both.

IF the data always contains these, then you can simplify to:

ages += person.ages.reduce((a, b) => a + b)
heights += person.heights.reduce((a, b) => a + b)


If the array always exists but could be zero length, then you will need to provide an initial value for reduce:

ages += person.ages.reduce((a, b) => a + b, 0)
heights += person.heights.reduce((a, b) => a + b, 0)


const data = [{personId: 1, ages: [1,4,5], heights: [1,1,2]}, {personId: 2, ages: [4,2,2], heights: [1,4,2]}, {personId: 2, ages: [2,1,1], heights: [12]}, {personId: 3, heights: []}];

function sumAgesAndHeights(data) {
let ages = 0;
let heights = 0;
data.forEach(person => {
ages += person.ages?.reduce((a, b) => a + b, 0) ?? 0;
heights += person.heights?.reduce((a, b) => a + b, 0) ?? 0;
})
return [
{
"types": "ages",
"values": ages
},
{
"types": "heights",
"values": heights
}
];
}

console.log(sumAgesAndHeights(data))