0

I want to merge related objects from two arrays.

var arr1 = [{thing: 'house', material: 'wood', location: 'earth'}, {thing: 'brick-wall', material: 'brick', location: 'moon'}];
var arr2 = [{property: 'made from wood', location: 'earth'}, {property: 'made from brick', location: 'moon'}];

Is it possible to join the two arrays in a way that will add the property value from arr2 to arr1 where arr1.location === arr2.location?

Alcides Queiroz
  • 9,456
  • 3
  • 28
  • 43
Znowman
  • 385
  • 1
  • 5
  • 19
  • 1
    join means mutation or do you want new objects? please add what you have tried? – Nina Scholz Mar 04 '18 at 16:17
  • 1
    Yes, it is possible. – lilezek Mar 04 '18 at 16:21
  • 1
    Please search before you ask. This kind of question has been asked many, many times before. – str Mar 04 '18 at 16:25
  • 1
    Possible duplicate of [Merge two array of objects with same keys, some object won't have the same value?](https://stackoverflow.com/questions/47713659/merge-two-array-of-objectsjson-with-same-keys-some-object-wont-have-the-same) – str Mar 04 '18 at 16:34

4 Answers4

3

You may use spread syntax with .map() and .find() array methods.

let arr1 = [
    {thing: 'house', material: 'wood', location: 'earth'},
    {thing: 'brick-wall', material: 'brick', location: 'moon'}
];
let arr2 = [
    {property: 'made from wood', location: 'earth'},
    {property: 'made from brick', location: 'moon'}
];

let result = arr1.map(o1 => ({
    ...o1, 
    property: arr2.find(o2 => o2.location === o1.location).property
}));

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

Alternatively you can use Object.assign():

let arr1 = [
    {thing: 'house', material: 'wood', location: 'earth'},
    {thing: 'brick-wall', material: 'brick', location: 'moon'}
];
let arr2 = [
    {property: 'made from wood', location: 'earth'},
    {property: 'made from brick', location: 'moon'}
];

let result = arr1.map(o1 => Object.assign(
  {property: arr2.find(o2 => o2.location === o1.location).property}, o1
));

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

Description:

  • .map() will create a new array from the results of callback function.
  • .find() will give us the object in second array where value of location property matches the property in current object being traversed in callback.

Useful Resources:

Mohammad Usman
  • 37,952
  • 20
  • 92
  • 95
0

You could concatenate the arrays. I assume you'd want to re-order from there or modify your key:value pairs, but pushing the two arrays into one is pretty straight forward at least.

var newArray = arr1.concat(arr2);

This will produce a new array called "newArray" but will leave your existing arrays as they stand.

hypern00b
  • 340
  • 1
  • 10
0

You can do it this way:

arr1.map(i1 => 
  ({ ...i1, property: (arr2.find(i2 => i2.location === i1.location) || {}).property }));
Alcides Queiroz
  • 9,456
  • 3
  • 28
  • 43
0

You could use a Map and build new objects as result

var arr1 = [{ thing: 'house', material: 'wood', location: 'earth' }, { thing: 'brick-wall', material: 'brick', location: 'moon' }],
    arr2 = [{ property: 'made from wood', location: 'earth' }, { property: 'made from brick', location: 'moon' }],
    map = new Map,
    result;

[arr1, arr2].forEach(a =>
    a.forEach(o => map.set(o.location, Object.assign(map.get(o.location) || {}, o))));

result = Array.from(map, ([k, v]) => v);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • You should mark this question as a clear duplicate instead of producing [similar answers](https://stackoverflow.com/a/47714013/906113) over and over again. – str Mar 04 '18 at 16:34