You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现分类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,因为它的标签包含所有筛选条件中的标签

逻辑解释

  1. 分类筛选:

    • 如果 filters.categories 是空数组,说明不需要筛选分类,直接返回true
    • 否则用 some() 检查当前项的分类中是否有slug存在于筛选分类数组中,只要有一个匹配就通过
  2. 标签筛选:

    • 如果 filters.tags 是空数组,说明不需要筛选标签,直接返回true
    • 否则用 every() 遍历筛选标签数组,确保每个标签slug都能在当前项的标签中找到(通过 some() 检查是否存在匹配的slug)
  3. 最终筛选:只有同时满足分类和标签条件的项才会被保留在结果数组中

内容的提问来源于stack exchange,提问作者Jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 16:22:04