简体   繁体   中英

How to most efficiently aggregate array of objects by ID?

My starting data set is an array of objects containing metrics, each containing an ID. I need to convert this data set into an array of aggregates, by ID. For example:

const startingArray = [
  { id: 1, metricA: 5, metricB: 8, metricC: 1 }
  { id: 2, metricA: 4, metricB: 0, metricC: 7 }
  { id: 1, metricA: 9, metricB: 8, metricC: 2 }
  { id: 3, metricA: 1, metricB: 8, metricC: 2 }
  { id: 3, metricA: 6, metricB: 6, metricC: 1 }
  { id: 2, metricA: 3, metricB: 1, metricC: 9 }
  { id: 1, metricA: 3, metricB: 9, metricC: 8 }
]

const aggregates = {};

startingArray.forEach((item) => {
  if (!aggregates[item.id]) {
    aggregates[item.id] = {
      id: item.id,
      metricA: item.metricA, 
      metricB: item.metricB, 
      metricC: item.metricC
    }
  } else {
    aggregates[item.id].metricA += item.metricA,
    aggregates[item.id].metricB += item.metricB,
    aggregates[item.id].metricC += item.metricC
  }
});

// convert to flat array using lodash toArray() method
const endingArray = toArray(aggregates);

// results:
// [
//   { id: 1, metricA: 17, metricB: 25, metricC: 11 }
//   { id: 2, metricA: 5, metricB: 1, metricC: 16 }
//   { id: 3, metricA: 5, metricB: 8, metricC: 3 }
// ]

The arrays can be massive, what is the most efficient way of processing this data set?

You could destructure id from the object and collect the rest for getting all entries and create a new object and sum all rest properties.

 const data = [{ id: 1, metricA: 5, metricB: 8, metricC: 1 }, { id: 2, metricA: 4, metricB: 0, metricC: 7 }, { id: 1, metricA: 9, metricB: 8, metricC: 2 }, { id: 3, metricA: 1, metricB: 8, metricC: 2 }, { id: 3, metricA: 6, metricB: 6, metricC: 1 }, { id: 2, metricA: 3, metricB: 1, metricC: 9 }, { id: 1, metricA: 3, metricB: 9, metricC: 8 }], result = Object.values(data.reduce((r, { id, ...o }) => { Object.entries(o).forEach(([k, v]) => { r[id]??= { id }; r[id][k] = (r[id][k] || 0) + v; }); return r; }, {})); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM