1

I have 2 different arrays I would like to merge.

var arr1 = [ { cardId: 1001, knowCnt: 0, dknowCnt: 1 }, { cardId: 1002, knowCnt: 0, dknowCnt: 2 }, { cardId: 1003, knowCnt: 1, dknowCnt: 3 } ];

var arr2= [
  {
    cardId: 1001,
    videoId: "l4LjOvERDoM",
    startSeconds: 5,
    endSeconds: 10,
  },

  {
    cardId: 1002,
    videoId: "jsFVnf3iF3w",
    startSeconds: 5,
    endSeconds: 10,
  },

  {
    cardId: 1003,
    videoId: "dc0q0H9CO9k",
    startSeconds: 5,
    endSeconds: 10,
  },

  {
    cardId: 1004,
    videoId: "kdZe5ZjfNX4",
    startSeconds: 5,
    endSeconds: 10,
  }
];

The 2 arrays have a matching cardId and I would like the knowCnt and dknowCnt in arr1 to be added to their respective cardId properties in arr2. A potential solution from here was:

    var mergeArrays = function() {
             var merged = [];

             const mergeById = (a1, a2) =>
                a1.map(itm => ({
                    ...a2.find((item) => (item.id === itm.id) && item), 
                    ...itm
                }));
            console.log(mergeById(arr1, arr2));
             }
      mergeArrays()

This works well but only returns the matching items. How can I return a single array with both the matching items (updated as above) but also including the remaining items from arr2. In other words the resulting array would look like arr2 but with 3 items updated from arr1? Note: the arrays may not be in matching order.

Thanks

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
quietplace
  • 471
  • 1
  • 4
  • 14

2 Answers2

1

You could take a Map and filter array2 by updateing know cardId.

var array1 = [{ cardId: 1001, knowCnt: 0, dknowCnt: 1 }, { cardId: 1002, knowCnt: 0, dknowCnt: 2 }, { cardId: 1003, knowCnt: 1, dknowCnt: 3 }],
    array2 = [{ cardId: 1001, videoId: "l4LjOvERDoM", startSeconds: 5, endSeconds: 10 }, { cardId: 1002, videoId: "jsFVnf3iF3w", startSeconds: 5, endSeconds: 10 }, { cardId: 1003, videoId: "dc0q0H9CO9k", startSeconds: 5, endSeconds: 10 }, { cardId: 1004, videoId: "kdZe5ZjfNX4", startSeconds: 5, endSeconds: 10 }],
    references = array1.reduce((m, o) => m.set(o.cardId, o), new Map),
    filtered2 = array2.filter(o => {
        if (!references.has(o.cardId)) return true;
        Object.assign(references.get(o.cardId), o);
    });

console.log(array1);
console.log(filtered2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Here is nothing complicated, just concat arrays and make one object by desirable key... Very simple code

const res = [...arr1, ...arr2].reduce((agg, v) => {
   agg[v.cardId] = Object.assign(agg[v.cardId] || {}, v)   
   return agg
}, {})

console.log(res)
Dmitry Reutov
  • 2,995
  • 1
  • 5
  • 20