如何利用嵌套数组的值过滤顶层数组?代码返回undefined
解决嵌套数组过滤顶层对象的问题
咱们先来捋清楚你代码里的几个核心问题,这就是为啥会返回undefined的原因:
- 解构只取了第一个dots元素:你用
({ dots: [event] })这种解构方式,只会把每个日期下dots数组的第一个元素赋值给event,完全忽略了数组里的其他项。比如2018-01-31里的第二个dot就没被检查到。 - filter回调没有返回值:你的回调函数里只执行了
event.categories.find(...),但没有把这个结果return出去。filter需要回调返回布尔值来决定是否保留当前项,没有返回值的话默认是undefined(等价于false),所以过滤后的数组是空的,pop()自然返回undefined。 - 结果结构不符合预期:你最后用
pop()只能拿到单个数组元素,但你想要的是保留原日期键的对象结构,而不是数组里的单个值。
接下来给你两种针对性的解决方案,对应不同的需求:
方案1:保留符合条件的日期项,且仅保留该日期下符合要求的dots
这完全匹配你给出的期望结果——既过滤掉没有目标category的日期,又在保留的日期里只留下符合条件的dots项:
const selectedId = 62; const events = { "2018-01-31": { dots: [{ key: "test", color: "red", categories: [{ name: "cat 1", id: 59 }, { name: "cat 2", id: 61 }, { name: "cat 3", id: 62 }] }, { key: "test again", color: "blue", categories: [{ name: "cat 1", id: 59 }, { name: "cat 2", id: 61 }] }] }, "2018-02-02": { dots: [{ key: "test 1", color: "blue", categories: [{ name: "cat 1", id: 59 }] }] }, "2018-02-04": { dots: [{ key: "test 2", color: "pink", categories: [{ name: "cat 1", id: 59 }] }, { key: "test 2", color: "pink", categories: [{ name: "cat 1", id: 59 }] }] } }; // 把对象转成键值对数组,过滤后再转回对象 const filteredEvents = Object.fromEntries( Object.entries(events) // 第一步:筛选出至少有一个dot符合条件的日期项 .filter(([date, { dots }]) => { return dots.some(dot => dot.categories.some(category => category.id === selectedId) ); }) // 第二步:对保留的日期项,过滤dots数组,只留下符合条件的dot .map(([date, { dots }]) => { const filteredDots = dots.filter(dot => dot.categories.some(category => category.id === selectedId) ); return [date, { dots: filteredDots }]; }) ); console.log(filteredEvents);
这段代码的逻辑很清晰:
- 用
Object.entries把原对象拆成[日期, 对应数据]的数组; - 先筛选出包含目标category的日期;
- 再对每个保留的日期,过滤内部的dots数组;
- 最后用
Object.fromEntries把处理后的键值对数组转回你需要的对象结构。
方案2:仅保留符合条件的日期项(不过滤dots内部)
如果你只需要过滤掉没有目标category的日期,不需要修改dots数组的内容,可以简化成:
const filteredEvents = Object.fromEntries( Object.entries(events).filter(([_, { dots }]) => dots.some(dot => dot.categories.some(cat => cat.id === selectedId)) ) );
这样得到的结果里,2018-01-31的dots会保留所有元素,其他不符合的日期会被直接过滤掉。
内容的提问来源于stack exchange,提问作者Bomber
相关产品推荐
相关产品推荐

