JavaScript:如何动态“过滤”我的对象

时间:2009-12-16 18:41:31

标签: javascript jquery html

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

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

我有以下JavaScript对象:

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

我正在使用JQuery来显示控件,以允许人们根据以下内容进行过滤:Price,Make,Year Built,Color

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

// 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 }).

4 个答案:

答案 0 :(得分:4)

  

如果已经设置过滤器,如何使用我的JQuery控件动态更改过滤器?

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

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

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

minprice= 20000;
result= cars.filter(minpricefilter);

答案 1 :(得分:2)

您可以使用函数发生器。

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

然后,当你过滤时,总是使用函数发生器。

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

答案 2 :(得分:0)

而不是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()即可重新生成整个表格。

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

答案 3 :(得分:0)

忘记基于回调的过滤。输入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倍,具体取决于你的表的大小。