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
CodePudding user response:
Without a clearly defined performance objective, it's hard to provide an answer that I feel is satisfying. However, I think this is readable, concise, and not wasteful:
function sumArrays (accumulator, obj) {
for (const [key, value] of Object.entries(obj)) {
if (!Array.isArray(value)) continue;
accumulator[key] ??= 0;
for (const n of value) accumulator[key] = n;
}
}
function getSums (array) {
const accumulator = {};
for (const obj of array) sumArrays(accumulator, obj);
return Object.entries(accumulator).map(([type, values]) => ({type, values}));
}
// Or, instead, optimized only for the input keys:
function getSumsOptimized (array, keysToSum) {
const result = keysToSum.map(type => ({type, values: 0}));
for (const obj of array) {
for (const [index, key] of keysToSum.entries()) {
for (const n of obj[key]) result[index].values = n;
}
}
return result;
}
const input = [
{ 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 ]},
];
console.log(getSums(input));
console.log(getSumsOptimized(input, ['ages', 'heights']));
CodePudding user response:
const 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
]
}
]
let heightsSum = 0;
let agesSum = 0;
array.forEach(element => {
element.ages.forEach(age => {
agesSum = age;
})
element.heights.forEach(height => {
heightsSum = height;
})
})
const arr = [
{
type: 'ages',
values: agesSum
},
{
type: 'heights',
values: heightsSum
}
]
console.log(arr)