1

Problem

I have two Javascript arrays of objects I need to merge. I need to merge by matching the unique values of a single key:value pair that are contained in each array. The keys for the values I want to merge based on are different

I want to add the key: value pairs from Array 2 to the correct object in Array 1 based on the matching unique value. The values for array1.user and array2._id are the values that I need to match by.

Arrays

const array1 = [ { _id: 5c6c7132f9bf4bdab9c906ff,
    user: 5c65d9438e4a834c8e85dd7d },
  { _id: 5c6ccd6d3a0dc4e4951c2bee,
    user: 5c65d9438e4a834c8e85dd7e } ]

const array2 = users [ { _id: 5c65d9438e4a834c8e85dd7d,
    info: { name: 'John', city: 'New York' } },
  { _id: 5c65d9438e4a834c8e85dd7e,
    info: { name: 'Paneer', city: 'San Fran' } } ]

What I've tried

I've tried using lodash's _.map and _.extend function like so but I'm new to lodash and it's not giving me the proper output

  const mergedArray = _.map(array1, function(item){
    return _.extend(item, _.find(array2, {_id: item.user}));
  });

Result

mergedArray [ { _id: 5c65d9438e4a834c8e85dd7d,
    info: { name: 'John', city: 'New York' } },
  { _id: 5c65d9438e4a834c8e85dd7e,
    info: { name: 'Paneer', city: 'San Fran' } }]

Desired Result

const mergedArray = [ { _id: 5c6c7132f9bf4bdab9c906ff,
    user: 5c65d9438e4a834c8e85dd7d,
    info: { name: 'John', city: 'New York' } } ,
  { _id: 5c6ccd6d3a0dc4e4951c2bee,
    user: 5c65d9438e4a834c8e85dd7e, 
    info: { name: 'Paneer', city: 'San Fran' } } ]

2
  • 1
    Why are they arrays? Is there a required sorting order? If not, you seem to have unique IDs, which makes the structure much more handy as an object where the _id is the key. Then you can easily look up by ID, and avoid all that iteration. Commented Apr 13, 2019 at 15:40
  • 1
    Possible duplicate of Merge two unordered objects with different keys but same value? Commented Apr 13, 2019 at 15:55

3 Answers 3

1

You can use map and find

In case your mapping of arrays are in same sequence than you can avoid use of find

const array1 = [ { _id: `5c6c7132f9bf4bdab9c906ff`,user: `5c65d9438e4a834c8e85dd7d` },{ _id: `5c6ccd6d3a0dc4e4951c2bee`,user: `5c65d9438e4a834c8e85dd7e` }]
const array2 =[ { _id: `5c65d9438e4a834c8e85dd7d`,info: { name: 'John', city: 'New York' } },{ _id: `5c65d9438e4a834c8e85dd7e`,info: { name: 'Paneer', city: 'San Fran' } } ]
    
const final = array1.map(e=> {
  const found = array2.find(({_id}) => e.user === _id)
  return {
    ...e,
    info : found.info
  }
})

console.log(final)

Sign up to request clarification or add additional context in comments.

1 Comment

The two arrays I need to merge are actually being returned from MongoDB and for some reason any method I've tried doesn't work, even though the same method works perfectly for a javascript array. Do you have any suggestions how to apply this solution to arrays returned from MongoDB? I'm using Mongoose if that makes a difference.
0

You could take a Map and build new object for the result.

const
    array1 = [{ _id: '5c6c7132f9bf4bdab9c906ff', user: '5c65d9438e4a834c8e85dd7d' }, { _id: '5c6ccd6d3a0dc4e4951c2bee', user: '5c65d9438e4a834c8e85dd7e' }],
    array2 = [{ _id: '5c65d9438e4a834c8e85dd7d', info: { name: 'John', city: 'New York' } }, { _id: '5c65d9438e4a834c8e85dd7e', info: { name: 'Paneer', city: 'San Fran' } }],
    users = new Map(array2.map(({ _id, info }) => [_id, { info }])),
    merged = array1.map(o => ({ ...o, ...(users.get(o.user) || {}) }));

console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

The two arrays I need to merge are actually being returned from MongoDB and for some reason any method I've tried doesn't work, even though the same method works perfectly for a javascript array. Do you have any suggestions how to apply this solution to arrays returned from MongoDB? I'm using Mongoose if that makes a difference.
0

An alternative is to generate an object with keys, and later get the values directly using that generated object. The key access is very fast.

const array1 = [ { _id: "5c6c7132f9bf4bdab9c906ff",user: "5c65d9438e4a834c8e85dd7d" },{ _id: "5c6ccd6d3a0dc4e4951c2bee",user: "5c65d9438e4a834c8e85dd7e" } ];
const ids = array1.reduce((a, {user, _id}) => ({...a, [user]: _id}), {});
const array2 = [ { _id: "5c65d9438e4a834c8e85dd7d",info: { name:'John', city: 'New York' } },{ _id: "5c65d9438e4a834c8e85dd7e", info: { name: 'Paneer', city: 'San Fran' } } ];
    
array2.forEach(o => {
  o.user = o._id;
  o._id = ids[o._id];
});

console.log(array2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.