简体   繁体   中英

How to merge two almost identical arrays/objects (with underscorejs or similiar libary)?

We got one old list and a new one. The Plan is to merge both even if some new key-value-pairs were added.

var oldList = [{
  id: 1,
  name: 'Michael',
  sex: 'male',
  goodlooking: 1
}, {
  id: 2,
  name: 'John',
  sex: 'male'
}, {
  id: 3,
  name: 'Laura',
  sex: 'female'
}];

AND...

var newList = [{
  id: 1,
  name: 'Cindy',
  sex: 'female'
}, {
  id: 2,
  name: 'Herry',
  sex: 'male'
}, {
  id: 3,
  name: 'Laura',
  sex: 'female',
  goodlooking: 1
}];

Now I am trying to merge these both together and get the most out of both by replacing the values of equal keys. In particular the merged list should look like this:

var mergedList = [{
  id: 1,
  name: 'Cindy',
  sex: 'female',
  goodlooking: 1
}, {
  id: 2,
  name: 'Herry',
  sex: 'male'
}, {
  id: 3,
  name: 'Laura',
  sex: 'female',
  goodlooking: 1
}];

Michael changed his name and sex, but stays goodlooking. John changed his name to Henry and Laura discovered her inner beauty.

var mergedList = _.map(oldList, function (oldElem) {
    var newElem = _.find(newList, {id: oldElem.id});
    return _.merge(oldElem, newElem);
});

A solution in plain Javascript:

 var oldList = [{ id: 1, name: 'Michael', sex: 'male', goodlooking: 1 }, { id: 2, name: 'John', sex: 'male' }, { id: 3, name: 'Laura', sex: 'female' }], newList = [{ id: 1, name: 'Cindy', sex: 'female' }, { id: 2, name: 'Herry', sex: 'male' }, { id: 3, name: 'Laura', sex: 'female', goodlooking: 1 }], theList = JSON.parse(JSON.stringify(oldList)); // make copy newList.forEach(function (a) { theList.some(function (b) { if (a.id === b.id) { Object.keys(a).forEach(function (k) { b[k] = a[k]; }); return true; } }); }); document.write('<pre>' + JSON.stringify(theList, 0, 4) + '</pre>'); 

Something like this maybe?

will override everything from the oldList with values available in the newList and adds new values if they are present.

mergedList = [];
_.each(oldList, function(listItem, index){
    copy = listItem;
    newValues = _.findWhere(newList, {"id": listItem.id});
    _.each(newValues, function(val,key){
        copy[key] = val;
    });
    mergedList[index] = copy
});

Somethink like this:

var a = oldList.length,
    mergedList = [];
while(a--){
    var oldData = oldList[a];
        newKeys = Object.keys(newList[a]);
    for (var i=0;i<newKeys.length;i++){
        var key = newKeys[i];
        oldData[key] = newList[a][key]
    }

}

Directly use lodash's merge method.

var mergedList = _.merge(oldList, newList);

It recursively merges own enumerable properties.
https://lodash.com/docs#merge

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM