提问者:小点点

JavaScript按id合并对象


在JavaScript中合并两个数组的正确方法是什么?

我有两个数组(例如):

var a1 = [{ id : 1, name : "test"}, { id : 2, name : "test2"}]
var a2 = [{ id : 1, count : "1"}, {id : 2, count : "2"}]

我希望能以这样的方式结束:

var a3 = [{ id : 1, name : "test", count : "1"}, 
          { id : 2, name : "test2", count : "2"}]

其中两个数组是基于“id”字段连接的,额外的数据只是简单地添加。

我尝试使用_.union来执行此操作,但它只是将第二个数组中的值覆盖到第一个数组中


共3个答案

匿名用户

这应该能奏效:

var mergedList = _.map(a1, function(item){
    return _.extend(item, _.findWhere(a2, { id: item.id }));
});

这假设a1中第二个对象的id应该是2而不是“2”

匿名用户

假设ID是字符串,并且顺序无关紧要,您可以

  1. 创建哈希表。
  2. 迭代这两个数组,并将数据存储在哈希表中,由ID索引。 如果已经有一些具有该ID的数据,请使用object.assign(ES6,可以是多填充的)更新它。
  3. 获取包含哈希映射值的数组。
var hash = Object.create(null);
a1.concat(a2).forEach(function(obj) {
    hash[obj.id] = Object.assign(hash[obj.id] || {}, obj);
});
var a3 = Object.keys(hash).map(function(key) {
    return hash[key];
});

在ECMAScript6中,如果ID不一定是字符串,则可以使用map:

var hash = new Map();
a1.concat(a2).forEach(function(obj) {
    hash.set(obj.id, Object.assign(hash.get(obj.id) || {}, obj))
});
var a3 = Array.from(hash.values());

匿名用户

ES6简化了这一点:

let merge = (obj1, obj2) => ({...obj1, ...obj2});

注意重复的键将被合并,并且以第二个对象的值为准,忽略第一个对象的重复值。

示例:

let obj1 = {id: 1, uniqueObj1Key: "uniqueKeyValueObj1", repeatedKey: "obj1Val"};
let obj2 = {id: 1, uniqueObj2Key: "uniqueKeyValueObj2", repeatedKey: "obj2Val"};

merge(obj1, obj2)
// {id: 1, uniqueObj1Key: "uniqueKeyValueObj1", repeatedKey: "obj2Val", uniqueObj2Key: "uniqueKeyValueObj2"}
merge(obj2, obj1)
// {id: 1, uniqueObj2Key: "uniqueKeyValueObj2", repeatedKey: "obj1Val", uniqueObj1Key: "uniqueKeyValueObj1"}
var a1 = [{ id : 1, name : "test"}, { id : 2, name : "test2"}]
var a2 = [{ id : 1, count : "1"}, {id : 2, count : "2"}]
var merge = (obj1, obj2) => ({...obj1, ...obj2});
_.zipWith(a1, a2, merge)
(2) [{…}, {…}]
   0: {id: 1, name: "test", count: "1"}
   1: {id: 2, name: "test2", count: "2"}

如果您有一组数组要合并,您可以这样做:

var arrayOfArraysToMerge = [a1, a2, a3, a4]; //a3 and a4 are arrays like a1 and a2 but with different properties and same IDs.
_.zipWith(...arrayOfArraysToMerge, merge)
(2) [{…}, {…}]
   0: {id: 1, name: "test", count: "1", extra1: "val1", extra2: 1}
   1: {id: 2, name: "test2", count: "2", extra1: "val2", extra2: 2}