如何将嵌套对象数组中的ID替换为匹配对象(10k+数据场景)
问题描述
现有包含10000+条记录的对象数组obj1,其中每个对象的technologies字段为ID字符串数组。需要遍历该数组,将每个ID与对象数组obj2的id字段匹配,用匹配到的obj2对象替换原ID,生成目标数组。
示例数据
obj1
obj1 = [ { "control_id": "red1234", "security_domain": "astrem", "control_statement": "testing", "descriptio": "test", "label": "minimal", "technologies": ["180"], "reference": {"string": "string"}, "evaluation": "", "category": null }, { "control_id": "red1234", "security_domain": "astrem", "control_statement": "testing", "descriptio": "test", "label": "minimal", "technologies": ["180", "320","3213"], "reference": {"string": "string"}, "evaluation": "", "category": null } ]
obj2
obj2 = [ {"id": 94,"name": "SUSE Linux Enterprise 12.x"}, {"id": 174,"name": "Ubuntu 18.x"}, {"id": 106,"name": "Windows 2016 Server"}, {"id": 180,"name": "Windows 2019 Server"}, {"id": 53,"name": "Windows 2012 Server"}, {"id": 217,"name": "Red Hat Enterprise Linux 8.x"}, {"id": 81,"name": "Red Hat Enterprise Linux 7.x"}, {"id": 109,"name": "Amazon Linux AMI"}, {"id": 126,"name": "Amazon Linux 2 AMI"}, {"id": 0,"name": "All OSs"}, {"id": 1,"name": "Windows Platforms"}, {"id": 2,"name": "Linux Platforms"}, {"id": 320,"name": "Windows 2012 Server"}, {"id": 3213,"name": "Windows 1999 Server"} ]
目标输出
obj1 = [ { "control_id": "red1234", "security_domain": "astrem", "control_statement": "testing", "descriptio": "test", "label": "minimal", "technologies": [{"id": 180,"name": "Windows 2019 Server"}], "reference": {"string": "string"}, "evaluation": "", "category": null }, { "control_id": "red1234", "security_domain": "astrem", "control_statement": "testing", "descriptio": "test", "label": "minimal", "technologies": [ {"id": 180,"name": "Windows 2019 Server"}, {"id": 320,"name": "Windows 2012 Server"}, {"id": 3213,"name": "Windows 1999 Server"} ], "reference": {"string": "string"}, "evaluation": "", "category": null } ]
尝试的错误代码
obj1.map(element => element.technologies.forEach((techArrayList, index) => this.operatingSystem.find(o => { if (techArrayList == o.id) { obj1[element.technologies].technologies[index].replace(o); } })));
解决方案
错误分析
forEach无返回值,在map中使用会导致最终结果数组全是undefinedobj1[element.technologies]写法错误:element.technologies是数组,不能作为索引访问obj1- 数组元素不能用
replace方法替换,需直接赋值 - 每次用
find遍历obj2查找匹配项,在10000+数据场景下效率极低
高效实现方案
先将obj2转换为映射表(Map),把id转为字符串作为键(因为obj1中的ID是字符串类型),对应对象作为值,这样查找匹配项的时间复杂度为O(1),大幅提升处理效率。之后遍历obj1,替换每个对象的technologies字段即可。
// 构建技术ID到对象的映射表 const techMap = new Map(obj2.map(item => [String(item.id), item])); // 生成目标数组,不修改原obj1 const targetArray = obj1.map(item => ({ // 复制原对象的所有属性 ...item, // 将technologies的ID字符串替换为匹配的obj2对象 technologies: item.technologies .map(techId => techMap.get(techId)) // 可选:过滤掉找不到匹配项的元素,若不需要可删除此句 .filter(Boolean) }));
代码说明
- 使用
Map构建映射表:仅遍历obj2一次,后续查找无需重复遍历 - 用扩展运算符
...item复制原对象,避免修改原数组obj1 technologies.map将每个ID字符串转换为对应的对象filter(Boolean)用于过滤找不到匹配项的ID(如果存在无效ID的情况)
内容的提问来源于stack exchange,提问作者Lanka
相关产品推荐
相关产品推荐

