【问题标题】:JavaScript: How do I dynamically "filter" my objectsJavaScript:如何动态“过滤”我的对象
【发布时间】:2010-12-27 08:49:47
【问题描述】:

如何使用 JavaScript“filter”属性过滤我的 JavaScript 对象?

我一直在阅读以下StackOverflow post,并且处于类似情况。

我有以下 JavaScript 对象:

{
'cars' : 
[{
"car_id"          : "1",
"price"           : "42999",
"make_id"         : "050",
"year_built"      : "2007",
"color_id"        : "832"
},
..........
]}

我正在使用 JQuery 来显示控件以允许人们根据以下条件进行过滤:价格、品牌、建造年份、颜色

根据其他帖子,我可以使用以下代码:

// if using an old browser, define the 'filter' attribute
if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

然后要执行实际的过滤器,我可以这样做:

result = cars.
  filter(function(p) { return p.price >= 15000 }).
  filter(function(p) { return p.price <= 40000 }).
  filter(function(p) { return p.year_built >= 2000 }) etc

我不明白的是,一旦设置了过滤器,我如何使用我的 JQuery 控件动态更改 filter 意思是,假设我已经应用了过滤器在上面,然后用户改变了主意,想要将他们愿意为汽车支付的最高金额从 40,000 美元增加到 50,000 美元。

我将如何修改我的过滤器:

  filter(function(p) { return p.price <= 40000 }).

到:

  filter(function(p) { return p.price <= 50000 }).

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

    一旦设置了过滤器,如何使用我的 JQuery 控件动态更改过滤器?

    您没有设置过滤器。您使用过滤器函数调用filter() 并返回过滤后的数组;您无法更改之后应用于数组的过滤器。相反,您必须再次调用filter(),并传递不同的过滤器函数。

    或相同的过滤器函数对已更改的变量进行闭包:

    var minprice= 10000;
    var minpricefilter= function(p) { return p.price>=minprice };
    result= cars.filter(minpricefilter);
    
    minprice= 20000;
    result= cars.filter(minpricefilter);
    

    【讨论】:

    • 这是我的解决方案的一个草率形式,但看看过滤器推理。
    【解决方案2】:

    你可以使用函数生成器。

    function createPriceFilter(price)
    {
       filter =  function(){ return p.price >= price };
       return filter;
    }
    

    然后,当您过滤时,请始终使用函数生成器。

    cars
        .filter( createPriceFilter( mySelectedPrice ) )
        .filter( createSomethingFilter(...) )
        . (...)
    

    【讨论】:

    • 也许我对 JavaScript 的了解不够,但这对 JavaScript 有什么帮助?这不是简单地执行完全相同的任务,而是现在需要我创建函数来代替
    【解决方案3】:

    代替filter,用一个普通的旧循环怎么样:

    var min_year = 2000;
    var min_price = 15000;
    var max_price = 40000;
    
    function fillTable() {
        clearTheTable();
        for (i = 0; i < cars.length; i++) {
            var car = cars[i];
            if (p.price >= min_price && p.price <= max_price && p.year_built >= min_year)
                addCarToTable(car);
        }
    }
    

    每次您的参数更改时,只需再次调用fillTable() 即可重新生成整个表。

    (你可以做很多更聪明的事情,但这是我能想到的最简单的事情。)

    【讨论】:

      【解决方案4】:

      忘记基于回调的过滤。输入 jOrder:http://github.com/danstocker/jorder

      通过遍历整个表格进行过滤既乏味又缓慢。使用 jOrder,您可以按索引搜索:

      var table = jOrder(json.cars)
          .index('id', ['car_id'])
          .index('price', ['price'], { grouped: true, ordered: true, type: jOrder.number })
          .index('maker', ['maker_id'], { grouped: true })
          .index('year', ['year_built'], { grouped: true, ordered: true, type: jOrder.number })
          .index('color', ['color_id'], { grouped: true });
      

      然后你得到你想要的记录:

      var filtered = table.where([{ price: { lower: 15000, upper: 40000 } }], { mode: jOrder.range });
      

      请注意,您一次只能应用一个不等式过滤器。要执行更多操作,请使用 filtered 作为不同 jOrder 表的输入,仅在其上放置必要的索引,然后对该表执行第二个不等式过滤器。等等。即使像这样堆叠几个过滤器,它仍然比迭代快 10 到 100 倍,具体取决于表的大小。

      【讨论】:

        猜你喜欢
        • 2022-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-13
        • 2020-07-21
        • 2020-05-29
        • 2015-09-28
        相关资源
        最近更新 更多