JS对象数组求Union结果不符预期,需保留数组a元素
问题原因与解决方案
错误原因
你的问题核心在于Map的键重复覆盖机制:当你通过[...a, ...b].map(ele => [ele.id, ele])生成键值对数组时,后续出现的相同id的键值对会覆盖之前的。因为你把b放在a后面拼接,所以b中相同id的对象会替换掉a里的原对象,最终Map中留存的自然是b的元素。
而调换a和b的顺序后,a的元素在拼接数组的末尾,会覆盖b中相同id的对象,所以能得到你想要的a的元素。
解决方案
如果你不能调换a和b的顺序,想要保留a的所有元素,同时将b中a没有的元素补充进并集,可以通过先构建a的Map,再按需添加b的元素实现:
const a = [ {id: "123", desc:"ItemOne", prdID:"PR-01"}, {id: "124", desc:"ItemTwo", prdID:"PR-02"} ]; const b = [ {id: "123", desc:"ItemOne", prdID:"PR-01", tbc:"yes"}, {id: "124", desc:"ItemTwo", prdID:"PR-02", tbc:"yes"}, {id: "124", desc:"ItemTwo", prdID:"PR-02", tbc:"no"}, {id: "125", desc:"ItemThree", prdID:"PR-03"} ]; // 先以a的元素初始化Map,确保a的元素被优先保留 const unionMap = new Map(a.map(item => [item.id, item])); // 遍历b,仅添加a中不存在的id对应的元素 b.forEach(item => { if (!unionMap.has(item.id)) { unionMap.set(item.id, item); } }); const Union = [...unionMap.values()]; console.log(Union);
这段代码会输出:
[ {id: "123", desc:"ItemOne", prdID:"PR-01"}, {id: "124", desc:"ItemTwo", prdID:"PR-02"}, {id: "125", desc:"ItemThree", prdID:"PR-03"} ]
完全符合你的需求:保留a的全部元素,同时补充b中a没有的元素,且a的元素不会被b覆盖。
内容的提问来源于stack exchange,提问作者Still_Learning
相关产品推荐
相关产品推荐

