Search code examples
javascriptarraysmergeextendlodash

Merge two arrays with objects


I plan to merge two objects:

var c = {
    name: "doo",
    arr: [
        {
            id: 1,
            ver: 1
        },
        {
            id: 3,
            ver: 3
        }
    ]
};


var b = {
    name: "moo",
    arr: [
        {
            id: 1,
            ver: 0
        },
        {
            id: 2,
            ver: 0
        }
    ]
};

When using Object.assign({},b,c) what happens is, that the b.arr is simply being replaced with c.arr.

My question is, how do I preserve objects inside the b.arr that are not in c.arr but still merge objects from that array when they match b.arr[0].id === c.arr[0].id. The desired outcome would look like:

{
    name: "doo",
    arr: [
        {
            id: 1,
            ver: 1
        },
        {
            id: 2,
            ver: 0
        },
        {
            id: 3,
            ver: 3
        }
    ]
}

Thanks.


Solution

  • As soon as you use lodash - you may use a combination of lodash's functions. It may look a bit complex but it's not:

    _.assign({}, b, c, function(objectValue, sourceValue, key, object, source) {
      //merging array - custom logic
      if (_.isArray(sourceValue)) {
        //if the property isn't set yet - copy sourceValue
        if (typeof objectValue == 'undefined') {
          return sourceValue.slice();
        } else if (_.isArray(objectValue)) {
          //if array already exists - merge 2 arrays
          _.forEach(sourceValue, function(sourceArrayItem) {
            //find object with the same ID's
            var objectArrayItem = _.find(objectValue, {id: sourceArrayItem.id});
            if (objectArrayItem) {
              //merge objects
              _.assign(objectArrayItem, sourceArrayItem);
            } else {
              objectValue.push(sourceArrayItem);
            }
          });
          return objectValue;
        }
      }
      //if sourceValue isn't array - simply use it
      return sourceValue;
    });
    

    See the full demo here.