Home > Enterprise >  Reducing Array of Objects to a single output
Reducing Array of Objects to a single output

Time:07-10

Hi I am trying to figure out the best way to achieve something. I essentially receive a lot of data like so

[
    {
    name: 'email.delivered',
    programme: 'Email One',
    timestamp: 2022-03-24T18:06:02.000Z,
    "payload":{
          "id":"bcabca7c-a5d5-4e02-b247-2292240ffc77",
      },
    },
    {
    name: 'interaction.click',
    programme: 'Email One',
    timestamp: 2022-03-24T18:06:02.000Z,
    "payload":{
        "correlation":{
           "channel":"email",
           "messageId":"bcabca7c-a5d5-4e02-b247-2292240ffc77",
        },
        "metadata":{
            "customerId":"9999999111",
            "programName":"Email One"
        }
      },
    },
    ...
]

The name is the event, can be delivered, failed, expired or click. The programme is what I want things categorised by. So I am doing some checks beforehand, and my code (removed a bit for simplicity) at the moment is like so

emails.forEach((record) => {
  const data = JSON.parse(record.data);
  if (data?.name === 'email.delivered') {
    const id = data?.payload?.id;
    if (!deliverDates[id]) deliverDates[id] = record.timestamp;
    deliveredMap.set(programme, (deliveredMap.get(programme) || 0)   1);
    return;
  }
  if (data?.name === 'email.click') {
    const id = data?.payload?.correlation?.messageId;
    if (id) {
      const deliveryDate = new Date(deliverDates[id]);
      if (deliveryDate.getTime() > Date.now() - 1209600000) {
        const programme = record?.programme;
        clicksMap.set(programme, (clicksMap.get(programme) || 0)   1);
      }
    }
  }
});

The problem with the above is now I now have two Maps, when really I want just one Object returned with the programme as the key. For each programme I want to count all the different event types. So what I would like to see is something more like this

{
  'Email One': {
    delivered: 315,
    failed: 18,
    expired: 14,
    click: 27,
  },
  'Email Two': {
    delivered: 542,
    failed: 322,
    expired: 33,
    click: 22,
  }
  ...
}

How can I achieve this?

Thanks

CodePudding user response:

Use a helper function to record the event occurence:

const eventCountsByProgramme = {};
function recordOccurence(programme, event) {
  const eventCounts = (eventCountsByProgramme[programme] ??= {});
  eventCounts[event] = (eventCounts[event] ?? 0)   1;
}

Then use

recordOccurence(programme, 'delivered');

instead of

deliveredMap.set(programme, (deliveredMap.get(programme) || 0)   1);

and

recordOccurence(programme, 'click');

instead of

clicksMap.set(programme, (clicksMap.get(programme) || 0)   1);
  • Related