Sumar valores de propiedad de objeto JavaScript con la misma propiedad de objeto B en una matriz de objetos
¿Cómo se tomaría una matriz de objetos de JavaScript, como
objArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:42},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23},
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:54} // <- duplicate key
]
¿Y fusionar claves duplicadas sumando los valores?
Para obtener algo como esto:
reducedObjArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:96},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23}
]
Intenté iterar y agregar a una nueva matriz, pero esto no funcionó:
var reducedObjArr = [];
var item = null, key = null;
for(var i=0; i<objArr.length; i++) {
item = objArr[i];
key = Object.keys(item)[0];
item = item[key];
if(!result[key]) {
result[key] = item;
} else {
result[key] += item;
}
}a
En lugar de usar un bucle for y enviar valores, puede usar directamente map y reducir :
let objArr = [
{key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42},
{key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78},
{key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23},
{key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54}
];
// first, convert data into a Map with reduce
let counts = objArr.reduce((prev, curr) => {
let count = prev.get(curr.key) || 0;
prev.set(curr.key, curr.val + count);
return prev;
}, new Map());
// then, map your counts object back to an array
let reducedObjArr = [...counts].map(([key, value]) => {
return {key, value}
})
console.log(reducedObjArr);
Deberías asignar cada objeto no encontrado al resultado con su .key
propiedad.
Si lo encuentra, deberá agregarlo .val
.
var temp = {};
var obj = null;
for(var i=0; i < objArr.length; i++) {
obj=objArr[i];
if(!temp[obj.key]) {
temp[obj.key] = obj;
} else {
temp[obj.key].val += obj.val;
}
}
var result = [];
for (var prop in temp)
result.push(temp[prop]);
Además, parte del problema era que estabas reutilizando la item
variable para hacer referencia al valor de .key
, por lo que perdiste la referencia al objeto.
Reducción más simple que la publicada en otros lugares ya que no utiliza un elemento de mapa
const objArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:42},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23},
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:54}];
const output = objArr.reduce((accumulator, cur) => {
let date = cur.key;
let found = accumulator.find(elem => elem.key === date)
if (found) found.val += cur.val;
else accumulator.push(cur);
return accumulator;
}, []);
console.log(output)
Podrías usar una tabla hash para agrupar por key
.
var array = [{ key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42 }, { key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78 }, { key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23 }, { key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54}],
grouped = [];
array.forEach(function (o) {
if (!this[o.key]) {
this[o.key] = { key: o.key, val: 0 };
grouped.push(this[o.key]);
}
this[o.key].val += o.val;
}, Object.create(null));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Otro enfoque es recopilar todos los pares clave/valor en Map
y formatear la matriz final con Array.from
una devolución de llamada para los objetos.
var array = [{ key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42 }, { key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78 }, { key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23 }, { key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54 }],
grouped = Array.from(
array.reduce((m, { key, val }) => m.set(key, (m.get(key) || 0) + val), new Map),
([key, val]) => ({ key, val })
);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var objArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:42},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23},
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:54}]
var targetObj = {};
for (var i = 0; i < objArr.length; i++) {
if (!targetObj.hasOwnProperty(objArr[i].key)) {
targetObj[objArr[i].key] = 0;
}
targetObj[objArr[i].key] += objArr[i].val;
}
console.log(targetObj);