Deep Merge Using Lodash

I have two arrays of objects that contain addresses that have a label and an object for the actual address:

var originalAddresses = [
  {
    label: 'home',
    address: { city: 'London', zipCode: '12345' }
  },
  {
    label: 'work',
    address: { city: 'New York', zipCode: '54321' }
  }
];

var updatedAddresses = [
  {
    label: 'home',
    address: { city: 'London (Central)', country: 'UK' }
  },
  {
    label: 'spain',
    address: { city: 'Madrid', zipCode: '55555' }
  }
];

Now I want to merge these arrays by label and compare the individual properties of the addresses and merge only the properties from the new address that are actually present. So the result should look like this:

var result = [
  {
    label: 'home',
    address: { city: 'London (Central)', zipCode: '12345', country: 'UK' }
  },
  {
    label: 'work',
    address: { city: 'New York', zipCode: '54321' }
  },
  {
    label: 'spain',
    address: { city: 'Madrid', zipCode: '55555' }
  }
]

How can I do this using lodash? I tried a combination of unionBy() and merge(). With unionBy() I was able to compare and join the arrays by label, but this always replaces the whole object. I can sure merge the addresses but this doesn't happen by label then.

2 Answers

You can turn both arrays into objects using _.keyBy(arr, 'label'), and then merge deep using _.merge():

var originalAddresses = [{
  label: 'home',
  address: {
    city: 'London',
    zipCode: '12345'
  }
}, {
  label: 'work',
  address: {
    city: 'New York',
    zipCode: '54321'
  }
}];

var updatedAddresses = [{
  label: 'home',
  address: {
    city: 'London (Central)',
    country: 'UK'
  }
}, {
  label: 'spain',
  address: {
    city: 'Madrid',
    zipCode: '55555'
  }
}];

var result = _.values(_.merge(
  _.keyBy(originalAddresses, 'label'),
  _.keyBy(updatedAddresses, 'label')
));

console.log(result);
<script src=""></script>
0

I try to use VanillaJS to handle this.

const originalAddresses = [{
    label: 'home',
    address: {
        city: 'London',
        zipCode: '12345'
    }
}, {
    label: 'work',
    address: {
        city: 'New York',
        zipCode: '54321'
    }
}];

const updatedAddresses = [{
    label: 'home',
    address: {
        city: 'London (Central)',
        country: 'UK'
    }
}, {
    label: 'spain',
    address: {
        city: 'Madrid',
        zipCode: '55555'
    }
}];


const groupBy = (array, property) => {
    return array.reduce((acc, cur) => {
            let key = cur[property]
            if (!acc[key]) {
                acc[key] = []
            }
            acc[key].push(cur)

            return acc
        }
        , {})
}

const groupByLabel = groupBy([...originalAddresses, ...updatedAddresses], 'label')

const result  = Object.keys(groupByLabel).map((key) => {
        return {
            label: groupByLabel[key][0].label,
            address: groupByLabel[key].reduce((acc, cur) => {
                    return Object.assign(acc, cur.address)
                }
                , {})
        }
    }
)
console.log(result)

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest