如何根据唯一dataKey为对象数组匹配添加指定fn属性
解决Obj1数组添加Obj2对应fn属性的问题
嘿,我看了你的需求和尝试的代码,其实你的实现逻辑是完全正确的,运行后应该能得到你想要的预期结果哦!不过如果后续数据量变大,两层嵌套的forEach效率会有点低,咱们可以优化一下写法,让代码更高效。
先确认你的需求要点:
- 必须保留Obj1的原有顺序,且不能移除任何对象
- 仅当Obj2中存在相同dataKey的对象,且该对象带有
fn属性时,才把这个fn添加到Obj1对应的对象中 - 不能修改Obj1原有对象的其他属性(比如你示例里Obj1中
bbb的flag还是要保持原来的false)
你的原代码为什么能工作?
你的两层forEach逻辑完全符合需求:遍历Obj1的每个对象,再在Obj2中找到对应dataKey且带有fn的对象,然后把fn赋值过去。这个逻辑没有问题,单独运行这段代码的话,输出的Obj1就是你想要的预期结果。
优化后的高效写法
如果处理的数组元素比较多,两层嵌套循环的时间复杂度是O(n*m),可以用Map来优化成O(n+m)的时间复杂度,代码更清晰高效:
let Obj1 = [ { "dataKey": "aaa", "title": "Lorem ipsum", "description": "Dolor sit", "flag": true }, { "dataKey": "ccc", "title": "dsff fsfsfs", "description": "dsd ds ds ds", "flag": false }, { "dataKey": "bbb", "title": "Duis aute irure", "description": "eu fugiat nulla pariatur", "flag": false }, { "dataKey": "ddd", "title": "Lorem ipsum dsds", "description": "Dolor sit dsdsds", "flag": true }, ]; let Obj2 = [ { "dataKey": "aaa", "title": "Lorem ipsum", "description": "Dolor sit", "flag": true, "fn": function() { console.log('hi'); } }, { "dataKey": "bbb", "title": "Duis aute irure", "description": "eu fugiat nulla pariatur", "flag": true }, { "dataKey": "ccc", "title": "dsff fsfsfs", "description": "dsd ds ds ds", "flag": true, "fn": function() { console.log('hi'); return 'abcd'; } }, ]; // 先把Obj2中带fn的项存入Map,key为dataKey,value为fn const fnMap = new Map(); Obj2.forEach(item => { if (item.fn) { fnMap.set(item.dataKey, item.fn); } }); // 遍历Obj1,给匹配的项添加fn属性 Obj1.forEach(item => { const targetFn = fnMap.get(item.dataKey); if (targetFn) { item.fn = targetFn; } }); console.log(Obj1);
优化思路说明:
- 先遍历一次Obj2,把所有带有
fn属性的对象的dataKey和对应的fn存入Map中,这样后续查找只需要O(1)的时间 - 再遍历一次Obj1,通过Map快速查找当前对象是否有对应的
fn,如果有就赋值过去 - 这种写法不仅效率更高,逻辑也更清晰,避免了嵌套循环的混乱
内容的提问来源于stack exchange,提问作者ketan
相关产品推荐
相关产品推荐

