skip to Main Content

I have two chat message arrays, each representing messages for a given date. I must merge these two arrays into a single object with the same date format. The object should contain all messages from both arrays, with the messages for each date merged.

Here is the data:

const data1 = {
  messages: {
    "27-04-2023": [
      {
        id: "SOkXFGtTwh",
      },
      {
        id: "i3NrqNyG9P",
      },
      {
        id: "lCmxr4rc5T",
      },
    ]
  }
};

const data2 = {
  messages: {
    "27-04-2023": [
      {
        id: "V9QzRgl6ji",
      },
      {
        id: "K5wfD-kX8W",
      }
    ],
    "24-04-2023": [
      {
        id: "tuarzhHPwH",
      },
      {
        id: "cbxu_dAeAj",
      },
      {
        id: "9xJpEJGUnm",
      }
    ]
  },
};

How to merge them to get the following output?

const data1 = {
  messages: {
    "27-04-2023": [
      {
        id: "SOkXFGtTwh"
      },
      {
        id: "i3NrqNyG9P"
      },
      {
        id: "lCmxr4rc5T"
      },
      {
        id: "V9QzRgl6ji"
      },
      {
        id: "K5wfD-kX8W"
      }
    ],

    "24-04-2023": [
      {
        id: "tuarzhHPwH"
      },
      {
        id: "cbxu_dAeAj"
      },
      {
        id: "9xJpEJGUnm"
      }
    ]
  }
};

What would be the best way to perform such task?

2

Answers


  1. You can consider using for-in and spread operator to merge 2 objects of arrays:

    const data1 = { messages: { '27-04-2023': [{ id: 'SOkXFGtTwh' }, { id: 'i3NrqNyG9P' }, { id: 'lCmxr4rc5T' }] }};
    const data2 = { messages: { '27-04-2023': [{ id: 'V9QzRgl6ji' }, { id: 'K5wfD-kX8W' }], '24-04-2023': [{ id: 'tuarzhHPwH' }, { id: 'cbxu_dAeAj' }, { id: '9xJpEJGUnm' }] }};
    
    function merge(obj1, obj2) {
      const output = {};
      for (const key in obj1) {
        output[key] = [...(obj1[key] || []), ...(obj2[key] || [])];
      }
      for (const key in obj2) {
        output[key] = [...(obj1[key] || []), ...(obj2[key] || [])];
      }
      return output;
    }
    
    console.log({ messages: merge(data1.messages, data2.messages) });
    Login or Signup to reply.
  2. This version merges any number of such objects into one, just allowing the property value from a later object override the same-named one from an earlier one, except for messages, which gets special handling: grabbing all the messages properties, converting them into a flat list of entries, and folding the results back into a single object:

    const mergeDates = (...ds) => ({
      ... Object .assign ({}, ...ds),
      messages: ds .flatMap (d => Object .entries (d .messages)) 
                   .reduce ((a, [k, vs]) => ((a [k] = (a [k] ?? []) .concat (vs)), a), {})
    })
    
    const data1 = {messages: {"27-04-2023": [{id: "SOkXFGtTwh"}, {id: "i3NrqNyG9P"}, {id: "lCmxr4rc5T"}]}}
    const data2 = {messages: {"27-04-2023": [{id: "V9QzRgl6ji"}, {id: "K5wfD-kX8W"}], "24-04-2023": [{id: "tuarzhHPwH"}, {id: "cbxu_dAeAj"}, {id: "9xJpEJGUnm"}]}}
    
    console .log (mergeDates (data1, data2))
    .as-console-wrapper {max-height: 100% !important; top: 0}

    If messages is your only property, you can remove the Object .assign line. Conversely, if you also need special handling for other properties besides messages, it’s easy to add additional ones parallel to messages.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search