Kako filtrirati predmetno polje na podlagi atributov?

Imam naslednje polje nepremičninskih objektov v javascriptu:

var json = {
    'homes': [{
            "home_id": "1",
            "price": "925",
            "sqft": "1100",
            "num_of_beds": "2",
            "num_of_baths": "2.0",
        }, {
            "home_id": "2",
            "price": "1425",
            "sqft": "1900",
            "num_of_beds": "4",
            "num_of_baths": "2.5",
        },
        // ... (more homes) ...     
    ]
}

var xmlhttp = eval('(' + json + ')');
homes = xmlhttp.homes;

Želel bi, da bi lahko izvedel filter na tem objektu in vrnil podmnožico objektov "home".

Na primer, želim, da bi lahko filtriral na podlagi: cena, kvadratna površina, število_ležišč in število_kopeli.

Kako lahko v javascriptu izvedem nekaj podobnega, kot je spodnja psevdokoda:

var newArray = homes.filter(
    price <= 1000 & 
    sqft >= 500 & 
    num_of_beds >=2 & 
    num_of_baths >= 2.5 );

Upoštevajte, da sintaksa ni nujno natanko takšna, kot je navedena zgoraj. To je le primer.

Rešitev

Uporabite lahko metodo Array.prototype.filter:

var newArray = homes.filter(function (el) {
  return el.price = 500 &&
         el.num_of_beds >=2 &&
         el.num_of_baths >= 2.5;
});

Primer v živo:

var obj = {
    'homes': [{
            "home_id": "1",
            "price": "925",
            "sqft": "1100",
            "num_of_beds": "2",
            "num_of_baths": "2.0",
        }, {
            "home_id": "2",
            "price": "1425",
            "sqft": "1900",
            "num_of_beds": "4",
            "num_of_baths": "2.5",
        },
        // ... (more homes) ...     
    ]
};
// (Note that because `price` and such are given as strings in your object,
// the below relies on the fact that = with a string and number
// will coerce the string to a number before comparing.)
var newArray = obj.homes.filter(function (el) {
  return el.price = 500 &&
         el.num_of_beds >= 2 &&
         el.num_of_baths >= 1.5; // Changed this so a home would match
});
console.log(newArray);

Ta metoda je del novega standarda ECMAScript 5th Edition in jo je mogoče najti v skoraj vseh sodobnih brskalnikih.

Za IE lahko zaradi združljivosti vključite naslednjo metodo:

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun /*, thisp*/) {
    var len = this.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 this) {
        var val = this[i];
        if (fun.call(thisp, val, i, this))
        res.push(val);
      }
    }
    return res;
  };
}
Komentarji (11)

Poskusite uporabiti ogrodje, kot je jLinq - spodaj je vzorec kode za uporabo jLinq.

var results = jLinq.from(data.users)
.startsWith("first", "a")
.orEndsWith("y")
.orderBy("admin", "age")
.select();

Za več informacij lahko sledite povezavi http://www.hugoware.net/projects/jlinq.

Komentarji (0)

To lahko storite zelo enostavno - verjetno obstaja veliko izvedb, med katerimi lahko izbirate, vendar je to moja osnovna zamisel (in verjetno obstaja kakšna oblika, v kateri lahko iterirate nad objektom z jQueryjem, vendar se je zdaj ne morem spomniti):

function filter(collection, predicate)
{
    var result = new Array();
    var length = collection.length;

    for(var j = 0; j < length; j++)
    {
        if(predicate(collection[j]) == true)
        {
             result.push(collection[j]);
        }
    }

    return result;
}

In potem bi lahko to funkcijo priklicali na naslednji način:

filter(json, function(element)
{
    if(element.price = 500 && element.num_of_beds > 2 && element.num_of_baths > 2.5)
        return true;

    return false;
});

Na ta način lahko filter sprožite na podlagi katerega koli predikata, ki ga določite, ali celo večkrat filtrirate z manjšimi filtri.

Komentarji (1)