JavaScript 如何按id列表从嵌套数组移除对象 解决map返回undefined问题
问题根因
之前的代码存在两处关键疏漏,才会导致最终返回[undefined, undefined]的结果:
Array.prototype.map方法的回调函数用花括号包裹了函数体,但内部没有写return语句,遍历每一个外层元素时,回调默认返回undefined,自然整个map的执行结果就是由两个undefined组成的数组Array.prototype.filter是无副作用的纯方法,不会修改调用它的原数组,执行后会返回一个符合过滤规则的全新数组;你之前的代码里直接把这个新数组丢弃了,既没有把它赋值给对应外层元素的data字段,也没有作为回调的返回值传递出去,就算filter内部的判断逻辑完全正确,过滤结果也不会被留存下来。
正确实现方案
推荐:不可变数据写法(无副作用,适配各类框架状态更新场景)
不修改原data数组,遍历生成全新的处理后数组,对每个外层元素:
- 保留原有所有属性(如
createOn) - 把
data字段替换为过滤后的结果,过滤规则和你原本写的一致:保留id不在listId中的子项
const remove = data.map(re => { return { ...re, data: re.data.filter(item => !listId.includes(item.id)) } })
执行后得到的remove数组就和你预期的结构完全一致,原data数组不会被改动。
如果用箭头函数直接返回对象的简写形式,代码可以进一步简化:
const remove = data.map(re => ({ ...re, data: re.data.filter(item => !listId.includes(item.id)) }))
直接修改原数据的写法
如果不需要保留原数组,也可以直接遍历外层元素,给每个元素的data属性重新赋值为过滤后的新数组:
data.forEach(re => { re.data = re.data.filter(item => !listId.includes(item.id)) })
这种写法会直接修改原data数组的内容,执行后原数组就会达到你要的删除效果,不需要额外接收返回值。
补充说明:你原本写的过滤判断逻辑(
!listId.includes(item.id))是完全正确的,不需要修改,只需要补上「返回处理结果」和「将过滤结果绑定到data字段」这两步即可。
内容的提问来源于stack exchange,提问作者Linh Nguyễn
相关产品推荐
相关产品推荐

