使用.map与.find匹配ID覆盖数组对象,为不匹配项添加nickName属性
解决JavaScript中.map和.find匹配后添加默认属性的问题
嘿,作为前端初学者遇到这种细节问题太正常了,我来帮你搞定它!
你的核心需求是:遍历arr1,用arr2中id匹配的对象覆盖arr1对应项,同时给没有匹配到id的对象加上nickName: 'none'属性。
问题出在哪?
你原来的代码里,当arr2.find(o => o.id === obj.id)找不到匹配项时,会直接返回原obj,而原obj本身没有nickName属性,所以结果里id为'2'的对象就缺了这个属性。
修改后的代码
直接上可以运行的解决方案:
const arr1 = [ {id: '1', name: 'A', surName: 'A', age: 30}, {id: '2', name: 'B', surName: 'B', age: 40}, {id: '3', name: 'C', surName: 'C', age: 50} ]; const arr2 = [ {id: '1', name: 'D', surName: 'D', age: 60, nickName: 'DD'}, {id: '5', name: 'E', surName: 'E', age: 70, nickName: 'EE'}, {id: '3', name: 'F', surName: 'F', age: 80, nickName: 'FF'} ]; let newArr = arr1.map(obj => { // 先获取arr2中匹配的对象 const matchedItem = arr2.find(o => o.id === obj.id); // 有匹配就用arr2的对象,没有就给原对象加上默认nickName return matchedItem ? matchedItem : {...obj, nickName: 'none'}; }); console.log(newArr);
运行结果
修改后你会得到每个对象都包含nickName属性:
0: {age: 60, id: "1", name: "D", nickName: "DD", surName: "D"} 1: {age: 40, id: "2", name: "B", surName: "B", nickName: "none"} 2: {age: 80, id: "3", name: "F", nickName: "FF", surName: "F"}
简化写法(一行搞定)
如果你喜欢更简洁的代码,也可以把逻辑压缩成一行:
let newArr = arr1.map(obj => arr2.find(o => o.id === obj.id) || {...obj, nickName: 'none'});
原理和上面一样:find返回匹配对象(存在时),否则执行后面的{...obj, nickName: 'none'},用对象扩展运算符...复制原对象所有属性,再添加默认的nickName。
额外优化(可选)
如果担心arr2中的对象可能本身没有nickName属性(虽然你当前的例子里都有),可以更严谨地确保最终每个对象都有这个属性:
let newArr = arr1.map(obj => { const matchedItem = arr2.find(o => o.id === obj.id); return { ...obj, // 先保留原对象的所有属性 ...matchedItem, // 用arr2的匹配对象覆盖同名属性 nickName: matchedItem?.nickName || 'none' // 兜底设置默认值 }; });
这里用了可选链操作符?.,避免matchedItem为undefined时报错,同时确保不管匹配对象有没有nickName,最终结果都不会缺这个属性。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

