I have array of objects like this and require to calculate running total(accumulate sum) dynamically for N keys.
let a = [
{"subject": "Civil", "a": 100, "b":50, "c":100 },
{"subject": "aero", "a": 200, "b":130,"c":100 },
{"subject": "tribe", "a": 100, "b":100,"c":600 },
{"subject": "solen", "a": 400, "b":150,"c":100},
{"subject": "space", "a": 100, "b":100,"c":900 }
];
Required Output as below :
[
{"subject": "Civil", "a": 100, "b": 50, "c": 100},
{"subject": "aero", "a": 300, "b": 180, "c": 200},
{"subject": "tribe", "a": 400, "b": 280, "c": 800},
{"subject": "solen", "a": 800, "b": 430, "c": 900},
{"subject": "space"," a": 900, "b": 530, "c": 1800}]
I tried below using MAP as below :
let b = a.map( x => ({...x,"a":a1 =x.a,"b":b1 =x.b,"c":c1 =x.c}) )
I want to achieve it dynamically without writing a, b, c.
CodePudding user response:
If you want to cumulatively sum every property other than subject
, you can do so by mapping the array to new values, keeping an object reference for each running total as you go
const a = [{"subject":"Civil","a":100,"b":50,"c":100},{"subject":"aero","a":200,"b":130,"c":100},{"subject":"tribe","a":100,"b":100,"c":600},{"subject":"solen","a":400,"b":150,"c":100},{"subject":"space","a":100,"b":100,"c":900}]
const cf = {} // store running totals in here
const b = a.map(({ subject, ...props }) => ({
subject,
...Object.fromEntries(Object.entries(props).map(([ key, val ]) => [
key,
cf[key] = (cf[key] ?? 0) val // value is the result of the assignment
]))
}))
console.log(b)
.as-console-wrapper { max-height: 100% !important; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can use a combination of .map()
, .slice()
and .reduce()
array methods as follows:
let a = [
{"subject": "Civil", "a": 100, "b":50, "c":100 },
{"subject": "aero", "a": 200, "b":130,"c":100 },
{"subject": "tribe", "a": 100, "b":100,"c":600 },
{"subject": "solen", "a": 400, "b":150,"c":100},
{"subject": "space", "a": 100, "b":100,"c":900 }
];
let b = a.map((x,i) => ({
subject:x.subject,
a:a.slice(0,i 1).map(({a}) => a).reduce((x,y) => x y),
b:a.slice(0,i 1).map(({b}) => b).reduce((x,y) => x y),
c:a.slice(0,i 1).map(({c}) => c).reduce((x,y) => x y)
}));
console.log( b );
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>