10

I have 2 array of objects:

const arr1 = [{'id':'1' 'value':'yes'}, {'id':'2', 'value':'no'}];
const arr2 = [{'id':'2', 'value':'yes'}];

So, if I try and merge these 2 arrays the result should be:

arrTemp = [{'id':'1', 'value':'yes'}, {'id':'2', 'value':'yes'}];

Basically, it should work similar to Object.assign(), but no matter what I try it does not work. Could anyone please help me in this ?

I modified the data structure. Is it possible to merge them now and get the output.

Thanks

3
  • How are you going to remove {'2':'no'}? Commented Nov 29, 2017 at 14:07
  • 2
    This datastrucure is so ugly. Commented Nov 29, 2017 at 14:08
  • Why are you using different keys in each object? Commented Nov 29, 2017 at 14:09

9 Answers 9

6

This is how you can get the job done with ES6 spread, reduce and Object.values.

const arr1 = [{
  'id': '1',
  'value': 'yes'
}, {
  'id': '2',
  'value': 'no'
}];
const arr2 = [{
  'id': '2',
  'value': 'yes'
}];

const result = Object.values([...arr1, ...arr2].reduce((result, {
  id,
  ...rest
}) => {
  result[id] = {
    ...(result[id] || {}),
    id,
    ...rest
  };
  return result;
}, {}));

console.log(result);

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

1 Comment

This is really great and is the most up to date answer, thanks for sharing!
3
const result = Object.entries(Object.assign({}, ...arr1,...arr2)).map(([key, value]) => ({[key]:value}));

You could spread (...) the arrays into one resulting object ( via Object.assign) and then map its entries to an array again.

2 Comments

It throws uncaughtException: Unexpected token : .I agree the datastructure is ugly, but cant change it now.
@ashy im sorry, fixed it ;)
2

You could work with a valid ES6 data structure like a map for example:

const 1 = { 1: { string: 'yes' }, 2: { string: 'no' } } const 2 = { 2: { string: 'yes' }, 3: { string: 'no' } } const 3 = { ...1, ...2}

This will override your first argument with the second one or just combine them where possible. Just try it out in your browser it's a lot easier and enhances performance since you will never have to use findById() which is an expensive operation.

1 Comment

findById() -> what should that be?! And identifiers cant start with a number!
2

In javascript, arrays are simply objects indexed by numbers starting from 0.

So when you use Object.assign on arr1 and arr2 you will override the first item in the arr1 with the first item in arr2 because they are both indexed under the key 0.

your result will be:

[
 { '2': 'yes' },
 { '2': 'no' }
]

(or in object syntax:)

{ 
 0: { '2': 'yes' },
 1: { '2': 'no' }
}

Instead of using arrays, you could create an object indexed by the number string (which is how you seem to be thinking of the array in any case).

So you could change your original data structure to make the job easier:

const arr1 = {
  '1': 'yes',
  '2': 'no'
};

const arr2 = {
  '2': 'yes'
};

const result = Object.assign(arr1, arr2);

2 Comments

Why not simply { 1:"yes", 2:"false" } then? In general I usually prefer using objects to arrays in javascript in most cases. -> thats the wrong approach. Choose the right one for the right job. Arrays are very very useful.
it is an array of very big objects.
0

You could take a Map as reference to the new assigned object in the result array and build first a new array with a copy of the objects and then iterate the second array and update the objects with the same key.

var array1 = [{ 1: 'yes' }, { 2: 'no' }],
    array2 = [{ 2: 'yes' }],
    getKey = o => Object.keys(o)[0],
    map = new Map,
    result = array1.map(o => (k => map.set(k, Object.assign({}, o)).get(k))(getKey(o)));

array2.forEach(o => Object.assign(map.get(getKey(o)), o));

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

Comments

0

Array reduce could come in handy is this case. See example below:

[...arr1, ...arr2].reduce((acc, item) => {
  const updated = acc.find(a => a.id === item.id)
  if (!updated) {
    acc.push(item)
  } else {
    const index = acc.indexOf(updated)
    acc[index] = { ...item, ...acc[index] }
  }
  return acc
}, [])

Comments

-1

simple way to add with exist array of object:

const arr1 = [{ "name":"John", "age":30, "car":"toyata" }];
const arr2 = [{ "name":"Ales", "age":40, "car":"Nissan" }];
Array.prototype.push.apply(arr1, arr2);

Result:=>
console.log(arr1)

Comments

-1

For anyone finding this answer at a later point in time. There are a couple of ways that you could want this to work exactly, but you could filter all adjusted elements in the first array, and then combine it with the second array.

const arr3 = [...arr1.filter(item1 => !arr2.find(item2 => item1.id === item2.id)), ...arr2]

Alternatively, you could update the elements in the first array, and then filter them from the second array instead.

Comments

-2

You cannot use array.prototype map because the key of arr1 and arr2 have the same value '2'.

You should use something like this

for (var i = 0, l = arr1.length; i < l; i++) {
 var key = Object.keys(arr1[i]);
 if (!arr2[key]) { arr2[key] = []; }
 arr2[key].push(arr1[i][key]);
}

Regards

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.