I have two arrays of objects like this:
const oldArr = [
{ 'Tomorrow': [{ id: 2 }, { id: 4 }, { id: 3 }] },
{ 'Saturday': [{ id: 2 }, { id: 4 }, { id: 3 }] }
]
const newArr = [
{ 'Monday': [{ id: 2 },{ id: 4},{ id: 3 }] },
{ 'Tomorrow': [{ id: 1 },{ id: 5 }]}
]
I want to merge both without any duplicate keys, so it should result in:
[
{ 'Tomorrow': [{ id: 2 }, { id: 4 }, { id: 3 }, { id: 1 }, { id: 5 }] },
{ 'Saturday': [{ id: 2 }, { id: 4 }, { id: 3 }] },
{ 'Monday': [{ id: 2 }, { id: 4 }, { id: 3 }] }
]
As you can see, the contents of Tomorrow
have been added to the original Tomorrow
, and the object of Monday
has been added on.
I've vaguely figured out how to do so with nested loops, but I'm guessing there is a simpler solution using map
, reduce
, or the like.
CodePudding user response:
This can be easily accomplished with a combination of the neat javascript spread syntax, Array and Object prototype functions, and destructuring patterns.
[...oldArr, ...newArr].flatMap(Object.entries).reduce(
(acc, [k, v]) => ({ ...acc, [k]: [...acc[k]||[], ...v] }), {})
As simple as this!
const oldArr = [
{'Tomorrow': [{'id':2},{'id':4},{'id':3}]},
{'Saturday': [{'id':2},{'id':4},{'id':3}]}
]
const newArr = [
{'Monday': [{'id':2},{'id':4},{'id': 3}]},
{'Tomorrow': [{'id':1},{'id':5}]}
]
const result = [...oldArr, ...newArr].flatMap(Object.entries).reduce(
(acc, [k, v]) => ({ ...acc, [k]: [...acc[k]||[], ...v] }), {})
console.log(result)
For a very detailed explanation of how this works, refer to this extended answer to a similar question. The difference in that other question is that there, each inner object had only one object as a value, instead of an array.
CodePudding user response:
This can be achieved by iterating the combined arrays to generate an object with all the values for each key in the arrays; then using Object.entries
to map that back to the original format:
const oldArr = [
{'Tomorrow': [{'id':2},{'id':4},{'id':3}]},
{'Saturday': [{'id':2},{'id':4},{'id':3}]}
]
const newArr = [
{'Monday': [{'id':2},{'id':4},{'id': 3}]},
{'Tomorrow': [{'id':1},{'id':5}]}
]
const result = Object.entries(oldArr.concat(newArr)
.reduce((a, o) => {
let k = Object.keys(o)[0]
a[k] = (a[k] || []).concat(o[k])
return a
}, {})
).map(([k, v]) => ({ [k] : v}))
console.log(result)