JavaScript: как динамически «фильтровать» мои объекты - PullRequest
1 голос
/ 16 декабря 2009

Как использовать атрибут JavaScript "filter" в качестве фильтра для моего объекта JavaScript?

Я читал следующее сообщение StackOverflow и нахожусь в аналогичной ситуации.

У меня есть следующий объект 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 }).

Ответы [ 4 ]

4 голосов
/ 16 декабря 2009

как использовать элементы управления 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 голосов
/ 16 декабря 2009

Вы можете использовать генератор функций.

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

Затем при фильтрации всегда используйте генератор функций.

cars
    .filter( createPriceFilter( mySelectedPrice ) )
    .filter( createSomethingFilter(...) )
    . (...)
0 голосов
/ 15 июля 2010

Забудьте фильтрацию на основе обратного вызова. Введите номер: 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 раз, в зависимости от размера вашей таблицы.

0 голосов
/ 16 декабря 2009

Вместо 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() снова, чтобы восстановить всю таблицу.

(Есть много более умных вещей, которые вы можете сделать, но это самая простая вещь, о которой я мог подумать.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...