Javascript 如何从一个对象数组中创建合并对象,该数组保留原始对象中的属性,而不是从新传入对象中更改

Javascript 如何从一个对象数组中创建合并对象,该数组保留原始对象中的属性,而不是从新传入对象中更改,javascript,arrays,mapping,javascript-objects,Javascript,Arrays,Mapping,Javascript Objects,我必须创建对象/数组集 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,并使用每

我必须创建对象/数组集

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);
const merged=test.mapele=>{ const found=test2.find{id}=>id==ele.id | |{} 返回{…ele,…found} } 循环试验 在test2中查找相同的id元素,如果未找到,请设置空对象 返回合并对象,其中test是源,test2包含覆盖/添加
试试这样的

常数测试=[{ id:1, 道具:“比尔”, 地点:“圣地亚哥” }, { id:11, 道具:“明亮” }, { id:12,//不在test2中 道具:“某物”, 地点:“纽约” }, { id:13,//test2中没有道具 道具:“某物”, 地点:“纽约” } ]; 常数test2=[{ id:1, 道具:“凯西” }, { id:'11', 道具:“蜡烛” }, { id:13, 有些东西:假的 }, { id:100,//不在测试中 道具:“其他” } ]; test.forEacht=>{ const t2=test2.findt2=>t2.id==t.id;//==用于精确匹配 如果t2 t、 prop=t2.prop | t.prop; };
控制台日志测试 使用Map函数提供此答案,以便可以首先将对象设置为键值。公认的答案简短明了,但这可能具有附加价值

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

  const map = new Map(test.map(obj => [obj.id, obj]));
  for (const item of test2) {
    if (map.has(item.id)) {
      // map.set( item.id, item ); // replace the item value
      map.set(item.id, { ...map.get(item.id),
        ...item
      }); 
    }
  }
  console.log(Array.from(map));

使用double equals==是个坏主意,字符串和数字ID将无法区分,并且merged@Marcin这是有目的的。在这种情况下,它们应该是不可区分的。对于没有从传入对象复制过来的属性,初始对象的完整性必须保持不变。我也想弄清楚为什么这是不够的。您的解决方案取决于与您要查找的属性相匹配的语句。而以上匹配整个对象。传入的内容必须覆盖它是少还是多。如果没有匹配的重写属性,则不能重写存在的内容。上面的解决方案更容易阅读,特别是使用您之前建议的KISS原则,正如您从代码片段中看到的,当id匹配松散==或精确===且属性prop存在于test2中时,测试会更新。应用KISS原则。好吧,那么我认为我做错了什么。。。本质上这是一样的,只是我的每个地图id都是一个值,所以当它在合并时合并整个值时,会得到替换。。。但是我需要每个对象来替换你所做的属性。有趣。如果我的解决方案是您正在寻找的,请将其标记为已接受的解决方案,或者请求进一步的帮助编辑它以使其工作,即使test2中没有成员