如何实现分类OR匹配、标签全匹配的对象数组过滤?
分类+标签组合筛选实现方案
首先先修正你提供代码中的语法错误(缺少逗号会导致代码无法运行):
filters对象中categories数组末尾需要添加逗号items数组中每个对象的categories属性末尾需要添加逗号items中标签对象的部分属性行(如Power Steering行)末尾缺少逗号
修正后的数据源
const filters = { categories: [ 'car', 'van', 'motorbike', ], // 补充逗号 tags: [ '4x4', 'petrol', 'sunroof' ] } const items = [ { title: '2016 VW Polo', categories: [ { title: 'Car', slug: 'car' } ], // 补充逗号 tags: [ { title: 'Sunroof', slug: 'sunroof', }, { title: 'Power Steering', // 补充逗号 slug: 'power-steering', }, { title: 'Petrol', // 补充逗号 slug: 'petrol', }, ] }, { title: '2015 Audi A4', categories: [ { title: 'Car', slug: 'car' } ], // 补充逗号 tags: [ { title: 'Sunroof', slug: 'sunroof', }, { title: 'Power Steering', // 补充逗号 slug: 'power-steering', }, { title: 'Petrol', // 补充逗号 slug: 'petrol', }, { title: '4x4', // 补充逗号 slug: '4x4', }, ] } ]
核心筛选逻辑实现
利用 Array.filter() 遍历待筛选数组,结合以下两个条件:
- 分类OR逻辑:用
Array.some()判断当前项的分类slug是否有任意一个匹配筛选条件中的分类 - 标签AND逻辑:用
Array.every()判断筛选条件中的所有标签slug,是否都能在当前项的标签中找到
完整代码:
const filteredItems = items.filter(item => { // 处理分类筛选:如果筛选分类为空则直接通过,否则匹配任一分类 const matchesCategory = filters.categories.length === 0 ? true : item.categories.some(cat => filters.categories.includes(cat.slug)); // 处理标签筛选:如果筛选标签为空则直接通过,否则匹配所有标签 const matchesTags = filters.tags.length === 0 ? true : filters.tags.every(tagSlug => item.tags.some(tag => tag.slug === tagSlug) ); // 同时满足分类和标签条件的项才保留 return matchesCategory && matchesTags; }); console.log(filteredItems); // 输出结果:仅包含2015 Audi A4,因为它的标签包含所有筛选条件中的标签
逻辑解释
分类筛选:
- 如果
filters.categories是空数组,说明不需要筛选分类,直接返回true - 否则用
some()检查当前项的分类中是否有slug存在于筛选分类数组中,只要有一个匹配就通过
- 如果
标签筛选:
- 如果
filters.tags是空数组,说明不需要筛选标签,直接返回true - 否则用
every()遍历筛选标签数组,确保每个标签slug都能在当前项的标签中找到(通过some()检查是否存在匹配的slug)
- 如果
最终筛选:只有同时满足分类和标签条件的项才会被保留在结果数组中
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

