Tengo una variedad de objetos como este y necesito calcular el total acumulado (suma acumulada) dinámicamente para N claves.
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 } ];Salida requerida de la siguiente manera:
[ {"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}]Probé a continuación usando MAP como se muestra a continuación:
let b = a.map( x => ({...x,"a":a1+=xa,"b":b1+=xb,"c":c1+=xc}) )Quiero lograrlo dinámicamente sin escribir a, b, c.
Si desea sumar de forma acumulativa todas las propiedades que no sean subject , puede hacerlo asignando la matriz a nuevos valores, manteniendo una referencia de objeto para cada total acumulado a medida que avanza.
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; }Puede usar una combinación de los métodos de matriz .map() , .slice() y .reduce() de la siguiente manera:
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 );Alternativamente, esto se puede hacer sin referencia a ninguna propiedad en particular de la siguiente manera:
let a = [ {"subject": "Civil", "a": 100, "b":50, "c":100, "zz":0}, {"subject": "aero", "a": 200, "b":130,"c":100, "zz":40}, {"subject": "tribe", "a": 100, "b":100,"c":600, "zz":0}, {"subject": "solen", "a": 400, "b":150,"c":100, "zz":60}, {"subject": "space", "a": 100, "b":100,"c":900, "zz":200} ]; let b = a.map((val, i) => ({ ...val, //introduce a temp property 'index' index: i + 1 })) .map(({ subject, index, ...rest }) => ({ subject, ...Object.keys(rest).reduce((obj, cur) => ({ ...obj, ...{ //use temp propterty to compute running total for every //property but 'subject', [cur]: a.slice(0, index).map(v => v[cur]).reduce((x, y) => x + y) } }), {}) })); console.log( b );