-1

i have this 2 array,

const firstArray = [
{
 key: 'a',
 value: 'a'
},
{
 key: 'b',
 value: 'b'
},
{
 key: 'c',
 value: 'c'
}
]

const secondArray = [
{
 key: 'b',
 value: 'd'
},
{
 key: 'c',
 value: 'e'
}
]

i want to merge these 2 array, and if a same key found on second array the second array value will replace first array value

the new array should look like this

const expectedArray = [
{
 key: 'a',
 value: 'a'
},
{
 key: 'b',
 value: 'd'
},
{
 key: 'c',
 value: 'e'
}
]
  • Does this answer your question? [Merge two array of objects based on a key](https://stackoverflow.com/questions/46849286/merge-two-array-of-objects-based-on-a-key) – pilchard Oct 17 '21 at 10:19
  • also [Merge Array of Objects by Property using Lodash](https://stackoverflow.com/questions/39127565/merge-array-of-objects-by-property-using-lodash/39127782) – pilchard Oct 17 '21 at 10:20
  • i think the second one is similar with mine, sorry i think i use wrong keyword when searching before post this question, @pilchard – tiwtiwtiwtiwaaaaa Oct 17 '21 at 11:08
  • no worries, it's okay to have duplicates but also good that they get linked as such to make a bigger pool of related answers. – pilchard Oct 17 '21 at 11:10

4 Answers4

2

As I see lodash in your tags, I assume you want to use it.

You can use something like this:

var merged = _(firstArray)
  .concat(secondArray)
  .groupBy("key")
  .map(_.spread(_.merge))
  .value();

It basically groups all objects with the same key into an array with groupBy("key"), then flattens out each array of values merging them and taking the last one with .map(_.spread(_.merge)).

I suggest commenting out the final likes and see all the intermediate steps if you want to fully understand the process, it's interesting!

const firstArray = [{
    key: 'a',
    value: 'a'
  },
  {
    key: 'b',
    value: 'b'
  },
  {
    key: 'c',
    value: 'c'
  }
]

const secondArray = [{
    key: 'b',
    value: 'd'
  },
  {
    key: 'c',
    value: 'e'
  }
]

var merged = _(firstArray)
  .concat(secondArray)
  .groupBy("key")
  .map(_.spread(_.merge))
  .value();

console.log(merged);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
Balastrong
  • 4,336
  • 2
  • 12
  • 31
  • wanna ask about the `_.spread(_.merge)`. so the spread will run merge for each description, and for `key a` since its just have one object inside, its just return same object, but for key b and c, because it have 2 object inside each key, it will be return last object. am i right? – tiwtiwtiwtiwaaaaa Oct 17 '21 at 09:19
  • Yes, at that point all items of each mapped array will have the same `key` value so it does not change, but for `description` (and more fields if there are) it will merge them all and take the last value. – Balastrong Oct 17 '21 at 09:27
1

Solution without lodash is to iterate through the second array and just look for matches.

If there's no match, push the item to the first array.

If there's a match, replace the item in the first array with the one from the second array.

const mergedArray = [...firstArray]

secondArray.forEach(newItem => {
  const matchIndex = mergedArray.findIndex(prevItem => prevItem.key === newItem.key)

  if (matchIndex === -1) {
    mergedArray.push(newItem)
  } else {
    mergedArray[matchIndex] = newItem
  }
})
Arnas Savickas
  • 354
  • 3
  • 10
0
const mergedArray = [...secondArray, ...firstArray];
const lengthOfUniqueArray = new Set(mergedArray.map((item) => item.key)).size;
const expectedArray = newArray.slice(0, lengthOfUniqueArray);

expectedArray will be what you want.

Ahmad
  • 49
  • 7
0

You can concat, reverse, can all unique elements by key, and then reverse back:

const { flow, concat, reverse, uniqBy } = _

const mergeArrays = flow(
  concat,
  reverse,
  arr => uniqBy(arr, 'key'),
  reverse
)

const firstArray = [{"key":"a","value":"a"},{"key":"b","value":"b"},{"key":"c","value":"c"}]
const secondArray = [{"key":"b","value":"d"},{"key":"c","value":"e"}]

var merged = mergeArrays(firstArray, secondArray)

console.log(merged)
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209