JS/TS如何将数组中对象属性合并到另一数组对应对象中
数组成员对象属性跨数组合并的简洁实现
需求背景
需要将一个数组中对应索引位置对象的属性,复制合并到另一个数组同索引的对象上,保留目标对象原有属性。现有手写双层循环的实现可以完成功能,但代码冗余,需要更优的实现方案。
原有实现代码及预期输出如下:
var first = [ { "AGREE_EFF_DATE__0": "02-Aug-2018", "AGREE_TERM_DATE__0": "30-Apr-2021", "AGREE_IND__0": "P1", "P_DBAR_IND__0": "N", "AGREE_EFF_DATE__1": "01-May-2021", "AGREE_TERM_DATE__1": null, "AGREE_IND__1": "NP", "P_DBAR_IND__1": "N", "PROVIDER_SPECIALITY__0": "PSYCHOLOGY, CLINICAL", "PROVIDER_SPECIALITY_CODE__0": "CK" } ]; var second = [ { "STATUS": "ACTIVE", "MEDICARE_NUMBER" : 12345 } ]; for(let i = 0; i < second.length; i++) { var first_keys = Object.keys(first[i]); var first_values = Object.values(first[i]); for(let j = 0; j < first_keys.length; j++) { second[i][first_keys[j]] = first_values[j]; } } console.log(second); // 预期输出 [ { STATUS: 'ACTIVE', MEDICARE_NUMBER: 12345, AGREE_EFF_DATE__0: '02-Aug-2018', AGREE_TERM_DATE__0: '30-Apr-2021', AGREE_IND__0: 'P1', P_DBAR_IND__0: 'N', AGREE_EFF_DATE__1: '01-May-2021', AGREE_TERM_DATE__1: null, AGREE_IND__1: 'NP', P_DBAR_IND__1: 'N', PROVIDER_SPECIALITY__0: 'PSYCHOLOGY, CLINICAL', PROVIDER_SPECIALITY_CODE__0: 'CK' } ]
更优实现方案
1. 原地修改版(和原有逻辑行为完全一致)
直接使用JS原生提供的对象合并APIObject.assign,不需要手动提取键值做双层循环,同时补上数组长度判断,避免两个数组长度不一致时出现越界报错:
for (let i = 0; i < Math.min(first.length, second.length); i++) { Object.assign(second[i], first[i]); }
这段代码的输出和原有实现完全一致,Object.assign是JS引擎原生实现的属性拷贝方法,性能比手写JS双层循环更好,代码可读性也更高。
2. 无副作用版(不修改原数组)
如果不希望修改原始的second数组数据,想要生成全新的合并结果(适合前端状态管理等不能直接修改源数据的场景),可以用对象展开运算符配合数组map方法实现:
const mergedResult = second.map((targetItem, index) => { const sourceItem = first[index]; return sourceItem ? { ...targetItem, ...sourceItem } : { ...targetItem }; });
这种写法是声明式逻辑,不需要手动维护循环下标,自动处理了first数组长度短于second的边界情况,不会抛出错误,最终返回的mergedResult就是合并完成的新数组,原始的first和second数组都不会被改动。
选型参考
- 需要直接修改原
second数组、和原有逻辑保持完全一致的行为:选Object.assign方案,代码最短,性能最优 - 需要保留原始输入数据、避免副作用:选展开运算符+
map的方案,数据安全性更高 - 两种方案都省略了手动提取对象键、值的冗余步骤,减少了手写循环可能引入的下标错误。
内容的提问来源于stack exchange,提问作者Priyam Mitra
相关产品推荐
相关产品推荐

