首页 > 解决方案 > 如何从一组对象中创建一个合并对象,该对象保留原始对象中的属性,而不是从新传入的对象中更改

问题描述

我必须对象/数组集...

var test = [{id: 1, prop: 'bill', location: 'san diego'},{id: 11, prop: 'bright'}];
var test2 = [{id: 1, prop: 'casey'},{id: 11, prop: 'candle'}];

最终,我希望 test2 中的对象更改 test 中的属性,但保留原始对象中的 location 属性,因为它没有更改甚至在 test2 中引用。

我所做的是设置一个映射,该键是 id 并使用每个对象作为值。

问题是每个键的新对象的值将完全覆盖以前的原始对象。因此, location 属性会从原始数组中删除。

特别是从 Object.assign() 中,未作为对象数组呈现的裸对象将保留原始对象的完整性,并且只会更改底层属性。

以下是两者的示例:

对象数组:

var o1 = [{id: 1, prop: 'bill', location: 'san diego'},{id: 11, prop: 'bright'}];
var o2 = [{id: 1, prop: 'casey'},{id: 11, prop: 'candle'}];
var o3 = { c: 3 };

var obj = Object.assign({}, o1, o2, o3);
console.log(obj); // 0: {id: 1, prop: "casey"} 1: {id: 11, prop: "candle"} c: 3

单一对象:

var o1 = {id: 1, prop: 'bill', location: 'san diego'};
var o2 = {id: 1, prop: 'casey'};
var o3 = { c: 3 };

var obj = Object.assign({}, o1, o2, o3);
console.log(obj); // {id: 1, prop: "casey", location: "san diego", c: 3}

以单一格式处理对象具有预期的效果,因此答案可能就在这个事实中。是否有一种简洁的方法来执行此操作,或者是否需要以循环方式构建,一次处理一条记录?如果是这样,这将是一个什么例子?

这是我正在处理的映射代码:

var test = [{id: 1, prop: 'bill', location: 'san diego'},{id: 11, prop: 'bright'}];
var first = new Map();
for (const value of test) {
    //console.log(key + ' = ' + value.id);
    first.set(value.id, value);
    //console.log(first);
}
var test2 = [{id: 1, prop: 'casey'},{id: 11, prop: 'candle'}];
var second = new Map();
for (const value of test2) {
    second.set(value.id, value);
}

var merged = new Map([...first, ...second]);

let mergedArray = [];
for (var value of merged.values()) {
  console.log(' = ' + value);
    mergedArray.push(value);
}

console.log('merged', mergedArray);
// console.log(merged)

// console.log('second2', second);
// console.log('first2 ', first);

标签: javascriptarraysmappingjavascript-objects

解决方案


const merged = test.map(ele => {
  const found = test2.find(({id}) => id === ele.id) || {}
  return {...ele, ...found}
})
  • 循环test
  • 在中找到相同的 id 元素test2(如果没有找到,则设置一个空对象)
  • 返回合并的对象,其中test是源并test2包含覆盖/添加

推荐阅读