J'ai le tableau JavaScript suivant d'objets de propriété immobilière:
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;
Ce que je voudrais faire est de pouvoir effectuer un filtre sur l'objet pour renvoyer un sous-ensemble d'objets "de base".
Par exemple, je veux pouvoir filtrer en fonction de: price
, sqft
, num_of_beds
et num_of_baths
.
Question: Comment puis-je effectuer quelque chose en JavaScript comme le pseudo-code ci-dessous:
var newArray = homes.filter(
price <= 1000 &
sqft >= 500 &
num_of_beds >=2 &
num_of_baths >= 2.5 );
Notez que la syntaxe ne doit pas nécessairement être exactement comme ci-dessus. C'est juste un exemple.
Vous pouvez utiliser la méthode Array.prototype.filter
:
var newArray = homes.filter(function (el) {
return el.price <= 1000 &&
el.sqft >= 500 &&
el.num_of_beds >=2 &&
el.num_of_baths >= 2.5;
});
Exemple en direct:
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 <= and >= with a string and number
// will coerce the string to a number before comparing.)
var newArray = obj.homes.filter(function (el) {
return el.price <= 1000 &&
el.sqft >= 500 &&
el.num_of_beds >= 2 &&
el.num_of_baths >= 1.5; // Changed this so a home would match
});
console.log(newArray);
Cette méthode fait partie de la nouvelle norme ECMAScript 5th Edition et peut être trouvée sur presque tous les navigateurs modernes.
Pour IE, vous pouvez inclure la méthode suivante pour la compatibilité:
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;
};
}
Vous pouvez essayer d’utiliser un framework comme jLinq - Voici un exemple de code permettant d’utiliser jLinq.
var results = jLinq.from(data.users)
.startsWith("first", "a")
.orEndsWith("y")
.orderBy("admin", "age")
.select();
Pour plus d'informations, vous pouvez suivre le lien http://www.hugoware.net/projects/jlinq
Je préfère le framework Underscore. Il suggère de nombreuses opérations utiles avec des objets . Votre tâche:
var newArray = homes.filter(
price <= 1000 &
sqft >= 500 &
num_of_beds >=2 &
num_of_baths >= 2.5);
peut être écrasé comme:
var newArray = _.filter (homes, function(home) {
return home.price<=1000 && sqft>=500 && num_of_beds>=2 && num_of_baths>=2.5;
});
J'espère que cela vous sera utile!
voici le violon qui fonctionne bien dans IE8 en utilisant la fonction jquery MAP
http://jsfiddle.net/533135/Cj4j7/
json.HOMES = $.map(json.HOMES, function(val, key) {
if (Number(val.price) <= 1000
&& Number(val.sqft) >= 500
&& Number(val.num_of_beds) >=2
&& Number(val.num_of_baths ) >= 2.5)
return val;
});
Vous pouvez le faire assez facilement - il y a probablement beaucoup d'implémentations parmi lesquelles vous pouvez choisir, mais c'est mon idée de base (et il existe probablement un format où vous pouvez itérer sur un objet avec jQuery, je n'arrive pas à y penser maintenant):
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;
}
Et ensuite, vous pouvez invoquer cette fonction comme suit:
filter(json, function(element)
{
if(element.price <= 1000 && element.sqft >= 500 && element.num_of_beds > 2 && element.num_of_baths > 2.5)
return true;
return false;
});
De cette façon, vous pouvez appeler le filtre en fonction du prédicat que vous définissez, ou même filtrer plusieurs fois à l'aide de filtres plus petits.
Vous pouvez utiliser jQuery.grep () depuis jQuery 1.0:
$.grep(homes, function (h) {
return h.price <= 1000
&& h.sqft >= 500
&& h.num_of_beds >= 2
&& h.num_of_baths >= 2.5
});
Vous pouvez implémenter vous-même une méthode de filtrage qui répond à vos besoins, voici comment:
function myfilter(array, test){
var passedTest =[];
for (var i = 0; i < array.length; i++) {
if(test( array[i]))
passedTest.Push(array[i]);
}
return passedTest;
}
var passedHomes = myfilter(homes,function(currentHome){
return ((currentHome.price <= 1000 )&& (currentHome.sqft >= 500 )&&(currentHome.num_of_beds >=2 )&&(currentHome.num_of_baths >= 2.5));
});
J'espère que ça aide!
Vous devriez vérifier OGX.List qui possède des méthodes de filtrage intégrées et étend le tableau javascript standard (ainsi que le regroupement, le tri et la recherche). Voici une liste des opérateurs pris en charge pour les filtres:
'eq' //Equal to
'eqjson' //For deep objects, JSON comparison, equal to
'neq' //Not equal to
'in' //Contains
'nin' //Doesn't contain
'lt' //Lesser than
'lte' //Lesser or equal to
'gt' //Greater than
'gte' //Greater or equal to
'btw' //Between, expects value to be array [_from_, _to_]
'substr' //Substring mode, equal to, expects value to be array [_from_, _to_, _niddle_]
'regex' //Regex match
Vous pouvez l'utiliser de cette façon
let list = new OGX.List(your_array);
list.addFilter('price', 'btw', 100, 500);
list.addFilter('sqft', 'gte', 500);
let filtered_list = list.filter();
Et vous pouvez ajouter autant de filtres que vous le souhaitez (un seul par propriété)
Ou vous pouvez simplement utiliser $.each
(qui fonctionne aussi pour les objets, pas seulement les tableaux) et construire un nouveau tableau comme ceci:
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) ...
{
"home_id": "3-will-be-matched",
"price": "925",
"sqft": "1000",
"num_of_beds": "2",
"num_of_baths": "2.5",
},
]
}
var homes = [];
$.each(json.homes, function(){
if (this.price <= 1000
&& this.sqft >= 500
&& this.num_of_beds >= 2
&& this.num_of_baths >= 2.5
) {
homes.Push(this);
}
});
var filterHome = homes.filter(home =>
return (home.price <= 999 &&
home.num_of_baths >= 2.5 &&
home.num_of_beds >=2 &&
home.sqft >= 998));
console.log(filterHome);
Vous pouvez utiliser cette fonction lambda. Plus de détails peuvent être trouvés ici puisque nous filtrons les données en fonction de votre condition qui renvoie true ou false et que les données seront collectées dans un tableau différent afin que votre tableau actuel ne soit pas modifié.
@JGreig S'il vous plaît examiner.
const x = JSON.stringify(data);
const y = 'search text';
const data = x.filter(res => {
return(JSON.stringify(res).toLocaleLowerCase()).match(x.toLocaleLowerCase());
});
Je suis surpris que personne n'ait posté la réponse d'une ligne:
const filteredHomes = json.homes.filter(x => x.price <= 1000 && x.sqft >= 500 && x.num_of_beds >=2 && x.num_of_baths >= 2.5);
... et pour que vous puissiez le lire plus facilement:
const filteredHomes = json.homes.filter( x =>
x.price <= 1000 &&
x.sqft >= 500 &&
x.num_of_beds >=2 &&
x.num_of_baths >= 2.5
);