ES6中能否嵌套使用filter?嵌套filter获取id返回undefined求助
关于ES6中嵌套使用filter及你的代码问题解答
首先明确:ES6完全支持嵌套使用filter,但你的代码问题出在逻辑判断和方法选择上,不是嵌套本身的问题。
先分析你的代码为什么输出undefined
你写的代码:
let activeFaq = this.faq.filter(obj => obj.items.filter(item => item.slug === 'slug')); console.log(activeFaq.id);
这里有两个核心问题:
- 外层
filter的判断逻辑错误:obj.items.filter(...)返回的是一个数组——哪怕没有匹配到任何item,它也是空数组[],而在JavaScript的布尔判断中,任何数组(包括空数组)都是truthy值,所以外层filter会把this.faq里的所有对象都保留下来,activeFaq最终是一个包含所有原数组元素的数组,而不是单个对象。 - 错误地访问数组的
id属性:activeFaq是数组,数组本身没有id属性,自然输出undefined。
针对你的需求的正确实现
假设你的this.faq数据结构大概是这样(符合你预期结果2729的场景):
this.faq = [ { id: 1001, items: [{ slug: 'test1', id: 2001 }, { slug: 'test2', id: 2002 }] }, { id: 2729, items: [{ slug: 'slug', id: 2003 }, { slug: 'other', id: 2004 }] }, // ...其他对象 ];
根据你说的“获取slug等于'slug'的项对应的id”,分两种常见场景给出解决方案:
场景1:获取包含该slug项的外层对象的id(即你预期的2729)
因为你只需要第一个匹配的外层对象(假设唯一),用find比filter更高效(find找到匹配项就停止遍历),同时用some判断内层数组是否存在符合条件的item(some返回布尔值,比filter更适合做存在性判断):
// 找到第一个包含slug为'slug'的item的外层对象 const targetFaq = this.faq.find(obj => obj.items.some(item => item.slug === 'slug') ); // 安全获取id(避免找不到时报错) const targetId = targetFaq ? targetFaq.id : null; console.log(targetId); // 输出2729
场景2:获取slug等于'slug'的item自身的id
如果你的需求是拿到那个匹配的item的id,可以先把所有内层item合并成一个数组,再用find定位:
// 扁平化所有items数组,找到匹配的item const targetItem = this.faq .flatMap(obj => obj.items) // 将所有内层items合并为一个数组 .find(item => item.slug === 'slug'); // 安全获取id const targetItemId = targetItem ? targetItem.id : null; console.log(targetItemId); // 输出对应的item id,比如2003
额外说明:什么时候适合嵌套使用filter?
如果你的需求是过滤外层数组,只保留那些内层数组有至少一个符合条件项的元素,并且需要保留多个结果,这时候可以嵌套filter,但外层的判断要改成检查内层filter的结果长度:
// 保留所有包含slug为'slug'的item的外层对象 const filteredFaqs = this.faq.filter(obj => obj.items.filter(item => item.slug === 'slug').length > 0 ); // 此时filteredFaqs是数组,你可以遍历它获取每个对象的id filteredFaqs.forEach(faq => console.log(faq.id));
不过这种写法不如用some高效,因为filter会遍历整个内层数组生成新数组,而some一旦找到匹配项就停止遍历。
内容的提问来源于stack exchange,提问作者michael
相关产品推荐
相关产品推荐

