将两个数组与对象合并

Merge two arrays with objects

本文关键字:数组 对象 合并 两个      更新时间:2023-09-26

我计划合并两个对象:

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
        }
    ]
};

当使用Object.assign({},b,c)时,会发生的情况是,b.arr只是被c.arr替换。

我的问题是,如何保留b.arr中不在c.arr中的对象,但当它们与b.arr[0].id === c.arr[0].id匹配时,仍然合并该数组中的对象。预期结果如下:

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

谢谢。

您可以从apache commons 中查看ArrayUtils.addAll()

一旦使用lodash,就可以使用lodash函数的组合。它看起来可能有点复杂,但事实并非如此:

_.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;
});

请在此处查看完整演示。

尝试此功能:

function mergeArrayObjects (a, b) {
    var tmp, // Temporary array that will be returned
        // Cache values
        i = 0,
        max = 0;
    // Check if a is an array
    if ( typeof a !== 'object' || typeof a.indexOf === 'undefined')
        return false;
    // Check if b is an array
    if ( typeof b !== 'object' || typeof b.indexOf === 'undefined')
        return false;
    // Populate tmp with a
    tmp = a;
    // For each item in b, check if a already has it. If not, add it.
    for (i = 0, max = b.length; i < max; i++) {
        if (tmp.indexOf(b[i]) === -1)
            tmp.push(b[i]);
    }
    // Return the array
    return tmp;
}

Js在此报价

注意:因为我是肛门,我决定看看这个函数是否比提出的替代方案更快。是.

使用lodash,我会做这样的事情:

var first = {
    name: 'doo',
    arr: [
        { id: 1, ver: 1 },
        { id: 3, ver: 3 }
    ]
};
var second = {
    name: 'moo',
    arr: [
        { id: 1, ver: 0 },
        { id: 2, ver: 0 }
    ]
};
_.merge(first, second, function(a, b) { 
    if (_.isArray(a)) {
        return _.uniq(_.union(a, b), 'id');
    } else {
        return a;
    }
});
// →
// {
//   name: 'doo',
//   arr: [
//     { id: 1, ver: 1 },
//     { id: 2, ver: 0 },
//     { id: 3, ver: 3 }
//   ]
// }

merge()函数允许您为数组之类的东西指定一个自定义回调。因此,我们只需要检查它是我们正在处理的数组,如果是,请使用uniq()和union()函数通过id属性查找唯一值。