如何根据ID匹配更新对象数组中嵌套对象的total属性值
解决数组对象匹配更新的问题
我来帮你分析一下问题所在,然后给出几种可行的解决方案。
你的代码为什么没生效?
你在map里的find回调中重新给item赋值了一个新对象,但这个操作只是在find回调内部创建了一个局部变量,并没有改变map回调里的item引用,也没有修改原对象的属性。最后map返回的还是原来的item,所以结果没有变化。
方案1:直接修改原数组(原地更新)
如果允许修改原数组的话,可以用forEach遍历arr1,找到匹配的arr2元素后直接更新value.total:
const arr1 = [ { id: 1, value: { total: 0 }, }, { id: 2, value: { total: 0 }, }, { id: 3, value: { total: 0 }, }, { id: 4, value: { total: 0 }, }, ]; const arr2 = [ { id: 2, value: 3 , }, { id: 3, value: 5, }, ]; arr1.forEach(item => { const match = arr2.find(element => element.id === item.id); if (match) { item.value.total = match.value; // *直接修改原对象的属性* } }); console.log(arr1); // 得到你想要的结果
方案2:返回新数组(不修改原数组)
如果希望保持原数组不变,返回一个新数组,可以在map里处理:
const arr1 = [ { id: 1, value: { total: 0 }, }, { id: 2, value: { total: 0 }, }, { id: 3, value: { total: 0 }, }, { id: 4, value: { total: 0 }, }, ]; const arr2 = [ { id: 2, value: 3 , }, { id: 3, value: 5, }, ]; const updatedArr1 = arr1.map(item => { const match = arr2.find(element => element.id === item.id); if (match) { // 返回新对象,不修改原对象 return { ...item, value: { ...item.value, total: match.value } }; } // 没有匹配的话返回原对象(也可以返回浅拷贝对象,根据需求调整) return item; }); console.log(updatedArr1); // 目标结果,原arr1不受影响
优化:提升查找效率
如果数组元素很多,每次用find遍历arr2的时间复杂度是O(n),可以先把arr2转成id映射对象,这样查找的时间复杂度降到O(1),性能会更好:
const arr1 = [ { id: 1, value: { total: 0 }, }, { id: 2, value: { total: 0 }, }, { id: 3, value: { total: 0 }, }, { id: 4, value: { total: 0 }, }, ]; const arr2 = [ { id: 2, value: 3 , }, { id: 3, value: 5, }, ]; // 先把arr2转换为以id为键的映射对象 const valueMap = arr2.reduce((acc, current) => { acc[current.id] = current.value; return acc; }, {}); const updatedArr1 = arr1.map(item => { if (valueMap[item.id] !== undefined) { return { ...item, value: { ...item.value, total: valueMap[item.id] } }; } return item; }); console.log(updatedArr1);
内容的提问来源于stack exchange,提问作者John_ny
相关产品推荐
相关产品推荐

