Michael
Michael

Reputation: 13616

Manipulating objects in array of objects

I have this javascript objects:

var arr1 = [{id:'124',name:'qqq'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'eee'},
           {id:'567',name:'rrr'}]

var arr2 = [{id:'124',name:'ttt'}, 
           {id:'45',name:'yyy'}

I need to replace objects in arr1 with items from arr2 with same id.

Here how I achive the desired result:

arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

And here is the result:

var arr1 = [{id:'124',name:'ttt'}, 
           {id:'589',name:'em'}, 
           {id:'45',name:'yyy'},
           {id:'567',name:'eme'}];

But the problem that this solution:

arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

Don't work in IE browser.

How can I change the row above to get the desired result in IE and chrome browsers?

var arr1 = [{
    id: '124',
    name: 'qqq'
}, {
    id: '589',
    name: 'www'
}, {
    id: '45',
    name: 'eee'
}, {
    id: '567',
    name: 'rrr'
}];

var arr2 = [{
    id: '124',
    name: 'ttt'
}, {
    id: '45',
    name: 'yyy'
}];

var res = arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

console.log(res);

Upvotes: 0

Views: 82

Answers (6)

Williz
Williz

Reputation: 309

What I would do is use a for loop to loop through each item in the 2nd array. Then loop through the first array to see if the ID matches. If it does, set the name to the name from the second array.

var arr1 = [{id:'124',name:'qqq'}, 
       {id:'589',name:'www'}, 
       {id:'45',name:'eee'},
       {id:'567',name:'rrr'}];

var arr2 = [{id:'124',name:'ttt'}, 
       {id:'45',name:'yyy'}];

for (var i = 0; i < arr2.length; i++) {
    for (var j = 0; j < arr1.length; j++) {
        if (arr2[i].id === arr1[j].id) {
            arr1[j].name = arr2[i].name;
        }
    }   
}

here is a fiddle https://jsfiddle.net/k0grurx5/

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386550

You could iterate over arr2 and build an object as hash table and then iterate over arr1 for changing the elements.

var arr1 = [{ id: '124', name: 'qqq' }, { id: '589', name: 'www' }, { id: '45', name: 'eee' }, { id: '567', name: 'rrr' }],
    arr2 = [{ id: '124', name: 'ttt' }, { id: '45', name: 'yyy' }],
    hash = Object.create(null);

arr2.forEach(function (a) {
    this[a.id] = a;
}, hash);

arr1.forEach(function (a, i, aa) {
    if (this[a.id]) {
        aa[i] = this[a.id];
    }
}, hash);

console.log(arr1);

Or use a version with short circuit.

var arr1 = [{ id: '124', name: 'qqq' }, { id: '589', name: 'www' }, { id: '45', name: 'eee' }, { id: '567', name: 'rrr' }],
    arr2 = [{ id: '124', name: 'ttt' }, { id: '45', name: 'yyy' }],
    hash = Object.create(null);

hash.count = arr2.length;

arr2.forEach(function (a) {
    this[a.id] = a;
}, hash);

arr1.some(function (a, i, aa) {
    if (this[a.id]) {
        aa[i] = this[a.id];
        return !--this.count;
    }
}, hash);

console.log(arr1);

Upvotes: 0

Abdelrahman M. Allam
Abdelrahman M. Allam

Reputation: 922

Please, did you think of underscorejs you will find cross browser functions like find, filter and map

 int lastIndex = 0 
 var result = _.map(arr1 , function(num){ 
      if (arr1.id == arr2[lastIndex].id){
         return arr2[lastIndex++];
      }
      return arr1;
 });

Upvotes: 0

noppa
noppa

Reputation: 4066

You have tagged lodash to this, so why not use lodash functions _ .find and _ .map instead of the native functions with limited browser support.

_.map(arr1, obj => _.find(arr2, o => o.id === obj.id) || obj);

To state the obvious, you also need to transpile the ES6 style arrow functions and what not to support older browsers.

Upvotes: 0

topheman
topheman

Reputation: 7902

If you don't want to use a polyfill, simply reduce the ids first then map.

var arr1 = [{id:'124',name:'qqq'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'eee'},
           {id:'567',name:'rrr'}]

var arr2 = [{id:'124',name:'ttt'}, 
           {id:'45',name:'yyy'}]

var byIds = arr2.reduce((acc, item) => {
    acc[item.id] = item;
    return acc;
}, {})

var replacedArr1 = arr1.map(item => byIds[item.id] || item);

Upvotes: 0

charlietfl
charlietfl

Reputation: 171679

If you want to use Array.prototype.find() you would need to use recommended polyfill for browsers that don't support it.

See MDN Array.protoype.find() polyfill

Upvotes: 1

Related Questions