У меня есть следующий JavaScript массив объектов домов недвижимости:
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;
Я хотел бы иметь возможность выполнить фильтр объекта, чтобы вернуть подмножество "домов".
Например, я хочу иметь возможность фильтровать на основе: price
, qft
, num_of_beds
, и num_of_baths
.
Как я могу сделать что-то на JavaScript, как в приведенном ниже псевдокоде:
var newArray = homes.filter(
price <= 1000 &
sqft >= 500 &
num_of_beds >=2 &
num_of_baths >= 2.5 );
Обратите внимание, синтаксис не обязательно должен быть точно таким, как указано выше. Это просто пример.
Вы можете использовать метод 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;
});
Живой пример:
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);
Этот метод является частью нового стандарта ECMAScript 5th Edition, и его можно найти почти во всех современных браузерах.
Для IE вы можете включить следующий метод для совместимости:
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;
};
}
Вы можете попробовать использовать фреймворк, например, jLinq - ниже приведен пример кода с использованием jLinq
var results = jLinq.from(data.users)
.startsWith("first", "a")
.orEndsWith("y")
.orderBy("admin", "age")
.select();
Для получения дополнительной информации вы можете перейти по ссылке http://www.hugoware.net/projects/jlinq.
Я предпочитаю подчеркнуть основу. Он предлагает множество полезных операций с объектами. Ваша задача:
var newArray = homes.filter(
price <= 1000 &
sqft >= 500 &
num_of_beds >=2 &
num_of_baths >= 2.5);
может быть overwriten как:
var newArray = _.filter (homes, function(home) {
return home.price<=1000 && sqft>=500 && num_of_beds>=2 && num_of_baths>=2.5;
});
Надеюсь, это будет полезно для вас!
вот рабочая скрипку, которая работает нормально в IE8 с помощью функции jQuery карте
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;
});
Вы можете сделать это довольно легко - вероятно, существует множество вариантов реализации, но это моя основная идея (и, вероятно, существует какой-то формат, в котором вы можете выполнять итерации над объектом с помощью jQuery, просто я не могу вспомнить его прямо сейчас):
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;
}
И затем вы можете вызвать эту функцию следующим образом:
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;
});
Таким образом, вы можете вызывать фильтр на основе любого предиката, который вы определите, или даже фильтровать несколько раз, используя меньшие фильтры.
Вы можете использовать jQuery.грэп() с помощью 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
});
Я'м удивлены, никто не опубликовал одну строку ответа:
const filteredHomes = json.homes.filter(x => x.price <= 1000 && x.sqft >= 500 && x.num_of_beds >=2 && x.num_of_baths >= 2.5);
...и точно так же вы можете читать ее легче:
const filteredHomes = json.homes.filter( x =>
x.price <= 1000 &&
x.sqft >= 500 &&
x.num_of_beds >=2 &&
x.num_of_baths >= 2.5
);
Вы можете реализовать метод фильтр самостоятельно, который отвечает вашим потребностям, вот как:
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));
});
Надеюсь, это поможет!
Вы должны проверить субтитры.Список, который имеет встроенные методы фильтрации и расширяет стандартную массива JavaScript (а также группирование, сортировка и поиск). Здесь's в список операторов он поддерживает для фильтров:
'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
Вы можете использовать его таким образом
let list = new OGX.List(your_array);
list.addFilter('price', 'btw', 100, 500);
list.addFilter('sqft', 'gte', 500);
let filtered_list = list.filter();
Или даже таким образом
let list = new OGX.List(your_array);
let filtered_list = list.get({price:{btw:[100,500]}, sqft:{gte:500}});
Или как один лайнер
let filtered_list = new OGX.List(your_array).get({price:{btw:[100,500]}, sqft:{gte:500}});
Или вы можете просто использовать $.каждый
(который также работает для объектов, не только массивы) и построить новый массив вот так:
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);
Вы можете использовать эту функцию лямбда. Более подробно можно найти здесь поскольку мы фильтрации данных на основе у вас есть условие, которое возвращает true или false и он будет собирать данные в другой массив, так что ваш фактический массив будет не изменен.
@JGreig пожалуйста, посмотрите в него.
const x = JSON.stringify(data);
const y = 'search text';
const data = x.filter(res => {
return(JSON.stringify(res).toLocaleLowerCase()).match(x.toLocaleLowerCase());
});
Я использую функцию мои ruleOut для объектов фильтрация на основе специфические значения свойств. Я понимаю, что в вашем примере вы хотите использовать условия вместо значения, но мой ответ действителен на заглавный вопрос, поэтому я'd, как покинуть мой способ здесь.
function ruleOut(arr, filterObj, applyAllFilters=true) {
return arr.filter( row => {
for (var field in filterObj) {
var val = row[field];
if (val) {
if (applyAllFilters && filterObj[field].indexOf(val) > -1) return false;
else if (!applyAllFilters) {
return filterObj[field].filter(function(filterValue){
return (val.indexOf(filterValue)>-1);
}).length == 0;
}
}
}
return true;
});
}
Скажем, у вас есть список таких актеров:
let actors = [
{userName:"Mary", job:"star", language:"Turkish"},
{userName:"John", job:"actor", language:"Turkish"},
{userName:"Takis", job:"star", language:"Greek"},
{userName:"Joe", job:"star", language:"Turkish"},
{userName:"Bill", job:"star", language:"Turkish"}
];
и вы хотели бы найти всех актеров, которые оцениваются как Голивуд звезд, их национальность не должна быть одним из 'английский', 'итальянский', 'испанский язык', 'греческий', плюс их имя не было бы ни одного из 'Мэри', 'Джо'. Bizzar примеру, я знаю! Во всяком случае, с тем набором условий, можно создать следующий объект:
let unwantedFieldsFilter= {
userName: ['Mary', 'Joe'],
job: ['actor'],
language: ['English', 'Italian', 'Spanish', 'Greek']
};
ОК, теперь, если вы ruleOut(актеры, unwantedFieldsFilter)
вам бы только вам
У [{имя пользователя: и"Билл" на, работу:, что "Звездой", язык: на "турецкий", у}]
А Билл-это твой человек, пока его имя не 'Мэри', 'Джо' его национальность не входит в ['английский язык', 'итальянский', 'испанский язык', 'греческий'] плюс он-звезда!
Есть один параметр в мой метод, то есть applyAllFilters и по умолчанию имеет значение true. Если ты попытаешься ruleOut этот параметр поставить в false, что будет работать как 'или' фильтрации вместо 'и'. Пример: `ruleOut(актеры, {задание: [на"актер", у], язык:["и итальянской" и]}, false), и будут вам все это не актер или итальянский:
У [{имя пользователя: и"Мэри" на, работу:, что "Звездой", язык: на "турецкий", у},<БР> {имя пользователя: "по-Такис-то", задание: на "Звездой", язык: на "греческий", у},<БР> {имя пользователя: на "Джо" на, работу:, что "Звездой", язык: на "турецкий", у},<БР> {имя пользователя: и"Билл" на, работу:, что "Звездой", язык: на "турецкий", у}]