Filtrowanie tablicy w javascript

Zadanie:
mamy w javascript tablicę obiektów, przykładowo strukturę jakiejś firmy:

var json = [
{
    "region_id" : "10",
    "obszar_id" : "15",
    "punkt_sprzedazy_id" : 25,
    "nazwa_punktu" : "Punkt 1"
},
{
    "region_id" : "10",
    "obszar_id" : "15",
    "punkt_sprzedazy_id" : 24,
    "nazwa_punktu" : "Punkt 2"
},
{
    "region_id" : "10",
    "obszar_id" : "15",
    "punkt_sprzedazy_id" : 27,
    "nazwa_punktu" : "Punkt 3"
},
{
    "region_id" : "10",
    "obszar_id" : "17",
    "punkt_sprzedazy_id" : 125,
    "nazwa_punktu" : "Punkt 41"
},
{
    "region_id" : "14",
    "obszar_id" : "9",
    "punkt_sprzedazy_id" : 205,
    "nazwa_punktu" : "Punkt 87"
},
{
    "region_id" : "6",
    "obszar_id" : "23",
    "punkt_sprzedazy_id" : 16,
    "nazwa_punktu" : "Punkt 42"
},
...
];

Teraz chcemy wybrać z tej tablicy tylko punkty sprzedaży z jednego obszaru – czyli np. elementy, dla których obszar_id == 15. Można do tego użyć zewnętrznych bibliotek operujących na formacie JSON, np: jOrder, JSONPath, Jaql, czy jLinq, albo wykorzystać obsługę Array.prototype.filter:

function wybierzPunktyZObszaru(obszar_id) {
    var Punkty = json.filter(function(el) {
        return el.obszar_id == obszar_id;
    });
    return Punkty;
}

Dla większej ilości warunków łączymy je:

var Punkty2 = json.filter(function(el) {
    return el.obszar_id == 15
    && el.punkt_sprzedazy_id >= 10;
});

lub

var Punkty3 = json.filter(function(el) {
    return el.obszar_id == 15;
}).filter(function(el) {
    return el.punkt_sprzedazy_id >= 10;
});

Więcej np. na stackoverflow.

Ważne, żeby dla przeglądarek nieobsługujących Array.prototype.filter dodać lokalną obsługę metody (za dokumentacją):

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

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

    return res;
  };
}

Taki fragment dodajemy np. na początku kodu.

Gdyby chcieć skorzystać przykładowo z biblioteki jOrder:

// utwórz obiekt tablicy jOrder i dodaj nieunikalny (grouped: true) indeks 'ix_obszar_id' na polu 'obszar_id'
var jsonTable = jOrder.table(json).index('ix_obszar_id', ['obszar_id'], {grouped : true});
// funkcja filtrująca, która zwraca tylko znalezione rekordy (renumber : true)
function szukajDaneZObszaru(obszar_id) {
    return jsonTable.where([{'obszar_id' : obszar_id}], {indexName : 'ix_obszar_id', renumber : true});
}
// wyszukaj punkty z obszaru 15
var Dane15 = szukajDaneZObszaru(15);

Więcej przykładów zastosowania jOrder na wiki projektu

IE + getElementById

W spadku po odchodzącym pracowniku dostałem do utrzymania aplikację WWW jego autorstwa. Trafił do mnie nierozwiązany przez niego problem działania jednego formularza. Pod Firefoxem działało bez zarzutu, pod IE nie chciało – podczas zapisu do bazy zamiast przesyłanej wartości wrzucane było ‚undefined’. Samo ustalanie wartości pola odbywało się przez taki kawałek kodu:

function $(id) {
return document.getElementById(id);
}
(...)
<input type="text" id="login" name="login" />

przesyłane parametry przez AJAX:

{login: $('login').value, imie: $('imie').value, nazwisko: $('nazwisko').value}

Problem pojawiał się przy polu login. Na szybko wystarczyło zmienić atrybuty name i id, ale skąd się wziął problem? Czytaj dalej