Skip to content
Advertisement

Is there an algorithm for merging elements of an array of objects with the same key

I have the following data, and I’ve been looking for a reference to an algorithm for building a returned array that is grouped by a field (e.g. discipline) and pushes in all the unique fields.

Initial Dataset:

[      
      { discipline: 1, originalBudgetDollars: 1114.96 },
      { discipline: 2, originalBudgetDollars: 192 },
      { discipline: 1, expendedDollars: 1137.24 },
      { discipline: 2, expendedDollars: 55.08 },
      { discipline: 1, forecastAtCompletionDollars: 1276.62 },
      { discipline: 2, forecastAtCompletionDollars: 96 },
      { discipline: 1, earnedValueDollars: 81.6 },
      { discipline: 2, earnedValueDollars: 10636.6 }
]

Desired Result:

[ 
      { discipline: 1, originalBudgetDollars: 1114.96, expendedDollars: 1137.24, remainingDollars: -22.28, forecastAtCompletionDollars: 1276.62, earnedValueDollars: 81.6 },
      { discipline: 2, originalBudgetDollars: 192, expendedDollars: 55.08,  remainingDollars: 136.92, forecastAtCompletionDollars: 96, earnedValueDollars: 10636.6 },
]

Advertisement

Answer

There is no particular algorithm for this problem, what you can do is break this problem into subproblem and get the desired results. The below snippet will also work if in the future you gonna add discipline: 3 data but there must be originalBudgetDollars and expendedDollars fields in the object (so that we can calculate remainingDollars).

Here I’ve used array reduce, Nullish coalescing, Object.values, forEach

const data = [
  { discipline: 1, originalBudgetDollars: 1114.96 },
  { discipline: 2, originalBudgetDollars: 192 },
  { discipline: 1, expendedDollars: 1137.24 },
  { discipline: 2, expendedDollars: 55.08 },
  { discipline: 1, forecastAtCompletionDollars: 1276.62 },
  { discipline: 2, forecastAtCompletionDollars: 96 },
  { discipline: 1, earnedValueDollars: 81.6 },
  { discipline: 2, earnedValueDollars: 10636.6 },
];

const obj = data.reduce((acc, curr) => {
  const { discipline } = curr;
  acc[discipline] = Object.assign(acc[discipline] ?? {}, curr);
  return acc;
}, {});

// Get only values of an object
const result = Object.values(obj);

// Adding remainingDollars in all object
result.forEach((obj) => {
  obj.remainingDollars = (
    obj.originalBudgetDollars - obj.expendedDollars
  ).toFixed(2);
});

console.log(result);
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement