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

JS多条件动态筛选餐厅对象 5星筛选失效与过滤逻辑修复

问题原因

现有代码存在3个核心问题导致筛选失效:

  • 过滤逻辑完全是反向排除设计:ruleOut函数的规则是「匹配到过滤字段值就排除该餐厅」,但5星筛选是正向匹配需求(勾选后需要保留5星餐厅、排除非5星),逻辑完全冲突,所以勾选5星反而会把所有5星餐厅排除掉
  • 复选框取值逻辑存在漏洞:未勾选选项时会向值数组插入空字符串,后续判断时空字符串会参与匹配,导致无勾选时过滤结果异常
  • 前三个复选框的value和label语义完全相反:比如标注「FastFood」的复选框value写的是dinner、标注「Open24」的复选框value写的是no、标注「Price $$」的复选框value写的是$,完全靠反向排除逻辑勉强凑出效果,和5星的正向筛选需求无法兼容
修复实现

直接把反向排除逻辑改成和用户操作直觉一致的正向多条件匹配:勾选某条件就保留符合该条件的餐厅,多勾选时取结果交集,未勾选的条件不做限制,同时修正复选框value对应关系。

修正后HTML部分(复选框value对齐语义)

<div class="container">
  <div id="buttons">
    <form action="" id="form">
      <input type="checkbox" id="fastfood" name="check" value="fastfood">
      <label for="fastfood"> FastFood</label>

      <input type="checkbox" id="open24" name="check" value="yes">
      <label for="open24"> Open24</label>

      <input type="checkbox" id="priceFilter" name="check" value="$$">
      <label for="priceFilter"> Price $$</label>

      <input type="checkbox" id="fiveStar" name="check" value="5">
      <label for="fiveStar"> 5 Stars</label>

      <input type="submit" value="Filter">
    </form>
  </div>

  <div id="target">
    <table>
      <tr>
        <th>Restaurant</th>
        <th>Type</th>
        <th>Open 24</th>
        <th>Price</th>
        <th>5 Stars</th>
      </tr>
      <tbody id="table"></tbody>
    </table>
  </div>
</div>

修正后JS部分(正向筛选逻辑)

let table = document.getElementById('table');
let form = document.getElementById('form');

const restaurants = [
  {name: "dennys", type: "dinner", open: "yes", price: "$$", stars: "5"},
  {name: "mcdonalds", type: "fastfood", open: "no", price: "$", stars: "3"},
  {name: "rubios", type: "fastfood", open: "yes", price: "$$", stars: "4"},
  {name: "polloloco", type: "fastfood", open: "no", price: "$", stars: "5"},
  {name: "kfc", type: "fastfood", open: "no", price: "$", stars: "3"},
  {name: "deltaco", type: "fastfood", open: "no", price: "$", stars: "1"},
  {name: "olivegarden", type: "dinner", open: "no", price: "$$", stars: "4"},
  {name: "fiveguys", type: "fastfood", open: "no", price: "$$", stars: "5"}
]

displayer(restaurants)

// 正向多条件筛选:返回满足所有选中条件的餐厅
function filterRestaurants(arr, selectedFilters) {
  return arr.filter(restaurant => {
    // 遍历所有选中的筛选条件,全部匹配才保留
    for (const [field, value] of Object.entries(selectedFilters)) {
      if (restaurant[field] !== value) return false
    }
    return true
  })
}

form.addEventListener('submit', (evt) => {
  evt.preventDefault()
  const checkboxes = document.getElementsByName('check');
  // 字段和复选框顺序对应:type、open、price、stars
  const fieldMap = ['type', 'open', 'price', 'stars']
  const selectedFilters = {}

  for (let i = 0; i < checkboxes.length; i++) {
    // 只收集勾选的条件,未勾选的不加入筛选规则
    if (checkboxes[i].checked) {
      selectedFilters[fieldMap[i]] = checkboxes[i].value
    }
  }

  const filtered = filterRestaurants(restaurants, selectedFilters);
  displayer(filtered)
})

function displayer(filtered) {
  table.innerHTML = "";
  filtered.forEach(rest => {
    table.innerHTML += `
    <tr>
      <td>${rest.name}</td>
      <td>${rest.type}</td>
      <td>${rest.open}</td>
      <td>${rest.price}</td>
      <td>${rest.stars}</td>
    </tr> `
  })
}

原有CSS代码不需要修改,保持样式即可。

修复后效果

  • 单独勾选「5 Stars」:返回所有星级为5的餐厅(dennys、polloloco、fiveguys)
  • 组合勾选「FastFood」+「5 Stars」:返回快餐类5星餐厅(polloloco、fiveguys)
  • 任意多条件组合都可以正常取交集筛选,无勾选时返回全部餐厅,完全符合操作预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:57:25