如何在JavaScript中合并两个对象数组?

3
这是一个示例,其中有两个数组,我们有一个merge()函数将这些数组作为参数进行合并。merge()应该返回合并后的数组,使得它可以合并具有相同名称的对象。
let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "person1@mail.com"
  },
  {
    name: "Person3",
    age: 25
  }
]


arr3 = merge(arr1, arr2)

output : 
arr3 should be : 
[
 {
    name: "Person1",
    age: 20,
    email: "person1@mail.com"
  },
   {
    name: "Person2",
    age: 30
  },
   {
    name: "Person3",
    age: 25
  }
]

2
这个回答解决了你的问题吗?如何在JavaScript中合并两个数组并去重 - Shatsuki
1
@Shatsuki 那个问题是关于合并字符串数组的,而这个问题是关于合并对象数组的,其中一些对象本身可能需要合并。 - Nick Parsons
你可以将问题分解为更小的子问题。首先从两个数组中识别出唯一的名称。然后,遍历这些名称并从两个数组中提取相应的属性来构建目标数组。如果可能的话,将尝试发布答案。 - jsN00b
1
名字相似还是相同?这两个词并不是同义词。 - Bravo
如果“Person3”在arr1和arr2中具有不同的年龄值,那么预期的行为是什么? - malarres
显示剩余3条评论
7个回答

3
你可以将一个对象作为哈希表来跟踪具有相同“name”的合并对象,并仅从哈希表中返回值。

const
    merge = (...arrays) => {
        const merged = {};
        
        arrays.forEach(data =>
            data.forEach(o => Object.assign(merged[o.name] ??= {}, o))
        );
        
        return Object.values(merged);
    },
    array1 = [{ name: "Person1", age: 20 }, { name: "Person2", age: 30 }],
    array2 = [{name: "Person1", email: "person1@mail.com" }, { name: "Person3", age: 25 }],
    result = merge(array1, array2);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


谢谢您的回答,能否请您帮我理解 ??= 运算符在 Object.assign(merged[o.name] ??= {}, o) 中代表什么意思? - shubham patil
这是一个逻辑空值赋值 ??=。这意味着,如果左侧(lhs)为 null 或 undefined,则会分配 rhs。 - Nina Scholz

2
你可以使用 lodash 来完成这项工作。

let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "person1@mail.com"
  },
  {
    name: "Person3",
    age: 25
  }
]


arr3 = _.merge(_.keyBy(arr1, 'name'), _.keyBy(arr2, 'name'));

console.log(arr3)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>


0

    let a = [
               {
                name: "Person15",
                age: 29
               },
               {
              name: "Person20",
          age: 39
         }
        ];;

            let b =  [
               {
                name: "Person1",
                age: 20
               },
               {
              name: "Person2",
          age: 30
         }
        ];

            // b diff a
            let resultA = b.filter(
              elm =>
                !a
                  .map(elm => JSON.stringify(elm)).includes(JSON.stringify(elm)),
            );

            // a diff b
            let resultB = a.filter(
              elm =>
                !b
                  .map(elm => JSON.stringify(elm)).includes(JSON.stringify(elm)),
            );

            // show merge
            
            const mergedArray = [ ...resultA, ...resultB ]


            const mergedArrays = [ ...b, ...mergedArray ]

            let newData = [
              ...new Map(mergedArrays.map(item => [item.id, item])).values(),
            ];
            console.log(newData);


0

map 部分涵盖了 arr1 中的每个项目,因此您可以将其原样添加或与 arr1 和 arr2 中都有的项目合并。然后您需要进行最后一次遍历以添加那些在 arr2 中但不在 arr1 中的项目。

let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "person1@mail.com"
  },
  {
    name: "Person3",
    age: 25
  }
]

const merge = (a1,a2) => {

return a1.map( (x) => {
  const y = a2.find( item => x.name === item.name);
  if (y) {
    return Object.assign({},x,y);
  } else
    return x
}).concat(a2.filter(item => a1.every( x => x.name !== item.name)));




}

arr3 = merge(arr1, arr2)

console.log(arr3)


0

我们可以将数组转换为对象,以获得更好的时间复杂度,然后使用展开运算符将它们合并,并在最后生成数组。

let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "person1@mail.com"
  },
  {
    name: "Person3",
    age: 25
  }
]
function merge(arr1, arr2){
  const merged_dict = {}
  const r_arr = []
  const arr = [...arr1,...arr2]
  arr.forEach(ele => {
    if(merged_dict[ele.name]){
      merged_dict[ele.name] = {...merged_dict[ele.name],...ele};
    }
    else{
      merged_dict[ele.name] = ele;
    }
  });
  for(let key in merged_dict){
    r_arr.push(merged_dict[key])
  }
  return r_arr
}

arr3 = merge(arr1, arr2)
console.log(arr3)


0

试试这个:

let arr1 = [{
    name: "Person1",
    age: 20
}, {
    name: "Person2",
    age: 30
}];
let arr2 = [{
    name: "Person1",
    email: "person1@mail.com"
}, {
    name: "Person3",
    age: 25
}];
function copy(source, destination) {
    for (let prop in source) {
        destination[prop] = source[prop];
    }
}
function merge(arr1, arr2) {
    let newArray = [];
    for (let i = 0, obj1; obj1 = arr1[i]; ++i) {
        let obj = {};
        copy(obj1, obj);
        for (let j = 0, obj2; obj2 = arr2[j]; ++j) {
            if (obj1.name === obj2.name) {
                copy(obj2, obj);
            }
        }
        newArray.push(obj);
    }
    for (let i = 0, obj2; obj2 = arr2[i]; ++i) {
        let here = false;
        for (let j = 0, obj1; obj1 = arr1[j]; ++j) {
            if (obj1.name === obj2.name) {
                here = true;
            }
        }
        if (!here) {
            newArray.push(obj2);
        }
    }
    return newArray;
}
let arr3 = merge(arr1, arr2);
console.log(arr3);


-1
  let arr1 = [
  {
   name: "Person1",
   age: 20
},
 {
 name: "Person2",
 age: 30
 }
]
 
let arr2 = [
 {
  name: "Person1",
  email: "person1@mail.com"
},
 {
   name: "Person3",
   age: 25
  }
] 


var arr3 = [...arr1,...arr2]

输出:0: {name: 'Person1', age: 20} 1: {name: 'Person2', age: 30} 2: {name: 'Person1', email: 'person1@mail.com'} 3: {name: 'Person3', age: 25}通过这个,我们将会有4个对象而不是3个。 - shubham patil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接