【问题标题】:JavaScript Array filter dynamicallyJavaScript 数组动态过滤
【发布时间】:2020-01-22 18:29:46
【问题描述】:

我想根据下拉选择过滤数组。我该怎么做呢

我的下拉菜单

<select class="custom-select" name="" id="Seats">
            <option selected value="">Any</option>
            <option value="le 5"><= 5</option>
            <option value="le 10"><= 10</option>
            <option value="le 15"><= 15</option> 
            <option value="le 20"><= 20</option>
            <option value="le 25"><= 25</option>
            <option value="le 30"><= 30</option> 
            <option value="le 35"><= 35</option> 
            <option value="le 50"><= 50</option> 
            <option value="gt 50">> 50</option>
          </select>

我正在过滤这样的东西(请注意 availableRooms 是数组列表)

availableRooms = availableRooms.filter(d => d.Seats > 50)

但我正在寻找动态查询

availableRooms = availableRooms.filter(d => d.Seats $("#Seats option:selected").text().trim())

最后一行给了我错误,我们该怎么做

【问题讨论】:

  • 错误是什么?
  • 什么是可用的房间?
  • 只是语法错误
  • try - (d =&gt; d.Seats&gt;parseInt($("#Seats option:selected").text().trim(),10)) - 语法错误,因为错过了&gt;,你需要整数转换
  • 怀疑你想覆盖变量availableRooms 并丢失原始数组的其余部分。如果用户进行另一个更改怎么办?还有数组是什么样子的……没有提供样本?

标签: javascript jquery arrays ecmascript-6


【解决方案1】:

您需要检测 legt 前缀并专门处理它们(除非您想开始使用 eval,您应该尽可能避免使用 - 而且您可以在这里)。例如:

$("#Seats").on("change", function() {
    let [op, value] = $(this).val().split(" ");
    value = +value; // Make it a number
    let filtered;
    if (op == "le") {
        filtered = availableRooms.filter(d => d.Seats <= value);
    } else { // Assume "gt"
        filtered = availableRooms.filter(d => d.Seats > value);
    }
    console.log(filtered);
});

现场示例:

const availableRooms = [
  {Seats: 51},
  {Seats: 50},
  {Seats: 49},
  {Seats: 34},
  {Seats: 29}
];

$("#Seats").on("change", function() {
    let [op, value] = $(this).val().split(" ");
    value = +value; // Make it a number
    let filtered;
    if (op == "le") {
        filtered = availableRooms.filter(d => d.Seats <= value);
    } else { // Assume "gt"
        filtered = availableRooms.filter(d => d.Seats > value);
    }
    console.log(filtered);
});
<select class="custom-select" name="" id="Seats">
    <option selected value="">Any</option>
    <option value="le 5"><= 5</option>
    <option value="le 10"><= 10</option>
    <option value="le 15"><= 15</option> 
    <option value="le 20"><= 20</option>
    <option value="le 25"><= 25</option>
    <option value="le 30"><= 30</option> 
    <option value="le 35"><= 35</option> 
    <option value="le 50"><= 50</option> 
    <option value="gt 50">> 50</option>
</select>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

【讨论】:

    【解决方案2】:

    根据' '拆分selectedOption,然后检查第一部分是'le'还是'ge'。在此基础上进行适当的比较。

    您可以使用String.prototype.split()split() 方法将 String 对象拆分为字符串数组,方法是将字符串分隔为子字符串,使用指定的分隔符字符串确定每次拆分的位置。

    availableRooms = availableRooms.filter(d => {
      var selectedOption=$("#Seats option:selected").text().trim().split(' ');
      if(selectedOption[0]==='le') {
        return d.Seats <= parseInt(selectedOption[1],10);
      } else if(selectedOption[0]==='ge') {
        return d.Seats > parseInt(selectedOption[1],10);    
      }
    })
    

    【讨论】:

      【解决方案3】:

      我建议使用 Vanilla JavaScript(即没有 jQuery)来应对这一挑战。您可以像这样获取&lt;select&gt; 元素:

      var dropdownEl = document.getElementById("Seats");
      

      然后像这样访问选定的选项:

      var dropdownValue = dropdownEl.options[dropdownEl.selectedIndex].value;
      

      然后按照你想要的方式过滤(假设过滤规则是你在上面写的d.Seats &gt; dropdownValue.trim()):

      availableRooms = availableRooms.filter(d => d.Seats > dropdownValue.trim());
      

      另一个重要提示 如果您可以将选项值转换为包含下拉选项的单个对象或数组,如下所示:

      var dropdownOptions: [
       {
         text: "<= 5",
         value: "le5"
       },
       {
         text: "<= 10",
         value: "le10"
       },
       {
         text: "<= 15",
         value: "le15"
       },
       ...
      ]
      

      您可以更轻松地呈现&lt;option&gt; 元素并为可见部分传递text 属性,然后可以轻松地回顾values,而无需像使用.text() 那样解析所选值和.trim() 或您将来可能需要对原始值进行的任何其他解析 - 所有这些都可以避免,您最终也会得到更优雅和可读的代码。

      【讨论】:

      • 没有String.prototype.text()
      • 我按照给定的示例进行了操作。这就是提问者的逻辑。但是好的会删除它
      • text() 是 jQuery 方法,你没有使用 jQuery
      • 没错,我不需要它,因为我得到的直接值已经是一个字符串了。
      【解决方案4】:
      var a = $("#Seats option:selected").val().split(' ');
      availableRooms = availableRooms.filter(d => {
        if (a[0] == 'le')
          return d.Seats <= parseInt(a[1])
        else 
          return d.Seats > parseInt(a[1])
      });
      

      【讨论】:

      • filter() 需要返回一个布尔值
      • 仍然有问题,覆盖变量没有意义,If 是一个错字
      • 还有什么问题?我很欣赏你的建议。想清除它并删除我的答案。
      猜你喜欢
      • 2022-09-24
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 2018-07-25
      • 1970-01-01
      • 2020-06-24
      • 2019-08-11
      相关资源
      最近更新 更多