-1

This is my current data structure

{
    key1: [
        {
            a: 123,
            b: 100,
            c: 300,
            start_date: “05-01-2021”
        },
        {
            a: 123,
            b: 100,
            c: 300,
            start_date: “06-01-2021”
        },
        {
            a: 123,
            b: 100,
            c: 300,
            start_date: “07-01-2021”
        }
    ],
    key2: [
        {
            a: 123,
            b: 100,
            start_date: “05-01-2021”
        },
        {
            a: 123,
            b: 100,
            start_date: “06-01-2021”
        },
        {
            a: 123,
            b: 100,
            start_date: “07-01-2021”
        }
    ]
}

Each object in the array has a key-value pair called start_date, which I am trying to match on.

Basically, I’m trying to each element in key1 that matches the start_time with each element in key2, and it can be for N number of key1 - keyN

I’ve tried some solutions with reduce, and running it through a loop, but I’m trying to find a elegant solution that doesn’t have me creating for loops.

The end result I want is:

{
    key1: [
        {
            a: 123,
            b: 100,
            c: 300,
            start_date: “05-01-2021”
        },
        {
            a: 123,
            b: 100,
            c: 300,
            start_date: “06-01-2021”
        },
        {
            a: 123,
            b: 100,
            c: 300,
            start_date: “07-01-2021”
        }
    ],
    key2: [
        {
            a: 123,
            b: 100,
            start_date: “05-01-2021”
        },
        {
            a: 123,
            b: 100,
            start_date: “06-01-2021”
        },
        {
            a: 123,
            b: 100,
            start_date: “07-01-2021”
        }
    ],
    key3: [
        {
            a: 246,
            b: 200,
            c: 300,
            start_date: “05-01-2021”
        },
        {
            a: 246,
            b: 200,
            c: 300,
            start_date: “06-01-2021”
        },
        {
            a: 246,
            b: 200,
            c: 300,
            start_date: “07-01-2021”
        }
    ]

}

All arrays will always be the same length.

hackerman90219
  • 81
  • 1
  • 1
  • 13

1 Answers1

0

You can use reduce(), flatMap() as well as Object.keys() and Object.values() in order to aggregate all the values in the input object.

Then use object destructuring and the spread syntax to create a new object which contains all previous objects as well as a new key with the aggregated values.

Here a working solution with comments explaining the steps.

const input = {
  key1: [
    {
      a: 123,
      b: 100,
      c: 300,
      start_date: "05-01-2021",
    },
    {
      a: 123,
      b: 100,
      c: 300,
      start_date: "06-01-2021",
    },
    {
      a: 123,
      b: 100,
      c: 300,
      start_date: "07-01-2021",
    },
  ],
  key2: [
    {
      a: 123,
      b: 100,
      start_date: "05-01-2021",
    },
    {
      a: 123,
      b: 100,
      start_date: "06-01-2021",
    },
    {
      a: 123,
      b: 100,
      start_date: "07-01-2021",
    },
  ],
};

// we only need the values
const aggregated = Object.values(input)
  // flatten it so we get one array with all entries
  .flatMap(x => x)
  // now reduce using start_date as a key
  .reduce((agg, cur) => {
    if (agg[cur.start_date]) {
      // we already have a key for this date => aggregate
      const toBeUpdated = agg[cur.start_date];
      // ever entry may have props...
      // - we already know     => aggregate/ sum up
      // - we do not yet know  => set property = current value of that entry
      Object.keys(cur).forEach(k => k !== "start_date" && toBeUpdated[k] ? toBeUpdated[k] += cur[k]: toBeUpdated[k] = cur[k]);
    } else agg[cur.start_date] = { ...cur }; // this is a new date => just copy the props and valus from the current enty
    return agg;
  }, {});
  
// this is the aggregation done
console.log("Result of aggregation:")
console.log(JSON.stringify(aggregated, null, 4));

console.log("Desired output:")
// Now create a new output object which has a new key value set to the values of what we've aggregated before
const output = {...input, [`key${Object.keys(input).length + 1}`]: Object.values(aggregated)};
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Mushroomator
  • 6,516
  • 1
  • 10
  • 27