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

Vanilla JS中对比数组嵌套对象状态筛选匹配活动的实现问题

问题分析

原有代码存在3个核心错误:

  • checkFilter 函数逻辑错误:filtersChecked 的每一项是单键对象(比如{free: true}),你现在直接把对应索引位置赋值为布尔值true/false,破坏了原有的数据结构,导致后续对比基准错误
  • 对象对比逻辑错误:用===对比两个对象会校验内存引用是否一致,就算两个对象内容完全一致也会返回false,无法正确判断筛选项值是否匹配
  • 匹配规则错误:你现在只要任意一个筛选项匹配就把活动名推入结果数组,实际需求是所有筛选项全部匹配才符合推入条件
修复后的原生JS实现

修正checkFilter函数

保持filtersChecked的单键对象结构不变,只修改对应键的值:

function checkFilter(index, isChecked) {
    // 获取当前索引对应筛选项的键名,比如索引0对应free
    const filterKey = Object.keys(model.input.filtersChecked[index])[0];
    model.input.filtersChecked[index] = {
        [filterKey]: isChecked
    };
}

重写suggestActivities函数

核心逻辑为:每个活动默认匹配,遍历所有筛选项校验,只要有一项不匹配就标记为不符合,全部校验通过才加入结果数组:

function suggestActivities() {
    const userFilters = model.input.filtersChecked;
    const matchedActivities = [];

    // 遍历所有待校验活动
    for (let i = 0; i < model.data.activities.length; i++) {
        const currentActivity = model.data.activities[i];
        const activityFilters = currentActivity.filters;
        let isAllMatch = true;

        // 逐位校验所有筛选项
        for (let j = 0; j < userFilters.length; j++) {
            const filterKey = Object.keys(userFilters[j])[0];
            const userSelectedVal = userFilters[j][filterKey];
            const activityVal = activityFilters[j][filterKey];

            // 规则:用户选null代表不限制该筛选项,否则必须和活动值完全相等
            if (userSelectedVal !== null && userSelectedVal !== activityVal) {
                isAllMatch = false;
                break; // 有一项不匹配就终止当前活动的校验
            }
        }

        if (isAllMatch) {
            matchedActivities.push(currentActivity.name);
        }
    }

    console.log(matchedActivities);
    return matchedActivities;
}
匹配规则说明
  • 用户筛选项为null时:该筛选项不生效,活动对应项无论为true/false/null都视为匹配
  • 用户筛选项为true/false时:活动对应项的值必须和用户选择的值完全相等才视为匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:36:09