I have arrays like this:
const one = [
{id: 1, field1: "a"},
{id: 2, field1: "b"},
{id: 3, field1: "c"},
{id: 4, field1: "d"}
]
const two = [
{id: 4, field2: "4"},
{id: 1, field2: "1"}
]
// what I want to achieve:
const result = [
{id: 1, field1: "a", field2: "1"},
{id: 4, field1: "d", field2: "4"}
]
I want to merge one and two, so I get the result. This is very similar to a SQL join, but I want to do all of this in JavaScript code. Notice:
id "column."one array (sorting by ID is only coincidentally the same order)I've figured out how to do this on my own, but the code is clunky and difficult to read. Basically, you filter over one and remove elements that don't exist in two, then you map over one and merge the fields of the two array.
Is there a more concise way of achieving this? I'm using lodash, and I was hoping there was a function in there to make this easier, but I haven't found any.
Create a dictionary or Map of the 2nd array by the key (id), and then filter the 1st array, and keep only items that appear in the dictionary. Afterwards, map the remaining items, and add the relevant items from the dictionary.
const joinBy = (arr1, arr2, key) => {
const arr2Dict = _.keyBy(arr2, key)
return arr1
.filter(item => item[key] in arr2Dict)
.map(item => ({ ...item, ...arr2Dict[item[key]] }))
}
const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}]
const two = [{id: 4, field2: "4"},{id: 1, field2: "1"}];
const result = joinBy(one, two, 'id')
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
If you don't want to use lodash, you can easily replace _.keyBy(), and create an object using Array.reduce() or create a Map with Array.map().
const joinBy = (arr1, arr2, key) => {
const arr2Dict = new Map(arr2.map(o => [o[key], o]))
return arr1
.filter(item => arr2Dict.has(item[key]))
.map(item => ({ ...item, ...arr2Dict.get(item[key]) }))
}
const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}]
const two = [{id: 4, field2: "4"},{id: 1, field2: "1"}];
const result = joinBy(one, two, 'id')
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With