Какой лучший способ запросить массив в javascript, чтобы получить только элементы из него, которые я хочу?
У меня есть массив вроде этого (с чуть более 3000 объектов вместо 3 здесь):
items = [{name:'charlie', age:'16'}, {name:'ben', age:'18'}, {name:'steve', age:'18'}]
Какой лучший способ вернуть массив только с объектами людей, которым 18? Поэтому я хочу:
items = [{name:'ben', age:'18'}, {name:'steve', age:'18'}]
Лучшее, что я могу придумать, это (с помощью jQuery):
newArray = []
$.each(items, function(index, item) {
if(item.age=='18') {
newArray.push(item)
}
})
Учитывая, что там 3000 тысяч объектов, а также то, что я буду делать это сравнение до пятидесяти раз за один ход, много циклов. Есть ли лучший способ?
Ответы
Ответ 1
Вы можете использовать чистый javascript
var wanted = items.filter( function(item){return (item.age==18);} );
И если ваш браузер не поддерживает версию javascript версии 1.6, вы можете найти реализацию метода фильтра в https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter
Обновление
В скорости есть огромный изменяющийся (имел ошибку в тесте) отличие от обычного цикла (в зависимости от браузера). Посмотрите на этот небольшой тест я сделал на http://jsperf.com/array-filter-vs-loop/3
Ответ 2
Если вы собираетесь часто выполнять поиск, лучше всего сохранить версию своих данных в форме, доступной быстро.
Я использовал underscore.js(http://documentcloud.github.com/underscore/), чтобы облегчить для себя, но этот код здесь создаст объект, который содержит ваши данные, индексированные по возрасту.
В итоге вы получите что-то похожее на это:
{
"16": [
{
"name": "charlie",
"age": "16"
}
],
"18": [
{
"name": "ben",
"age": "18"
},
{
"name": "steve",
"age": "18"
}
]
}
Код:
var itemsByAge = _(items).reduce(function(memo, item) {
memo[item.age] = memo[item.age] || [];
memo[item.age].push(item);
return memo;
}, {});
alert(JSON.stringify(itemsByAge["18"]));
Ответ 3
Независимо от того, какой метод вы выберете (items.filter или любой "язык запросов" для json), цикл for неизбежен.
Если производительность является проблемой, я бы рекомендовал использовать чистый javascript вместо библиотек, таких как jQuery, которые добавят накладные расходы для всей обработки, как очевидно здесь.
Таким образом, ваш код будет выглядеть так:
var newArray = [];
for(var i=0;i<items.length;i++) {
var item = items[i];
if(item.age == '18') {
newArray.push(item);
}
});
Ответ 4
используя великолепную функцию javascript eval()
, которая оценивает строку как код во время выполнения, мы можем определить метод прототипа для типа массива
Array.prototype.where = function (query) {
var newArray = [];
for(var i=0; i<this.length; i++) {
var item = this[i];
if(eval( "item" + query )) {
newArray.push(item);
}
}
return newArray;
};
и использовать его с любым массивом, передавая запрос как строку
var newArray= items.where('.age >= 18');
Ответ 5
Использовать метод фильтра для массива, он вызывает предоставленную функцию обратного вызова один раз для каждого элемента в массиве.
array.filter(<callbackfucntion>[, <Object to use>])
Ответ 6
как только у меня возникла такая проблема, и я решил ее так
1- создать массив массива
2- каждый индекс создает запись индекса
например.
var pAry=[];
var cAry=[{name:'ben', age:'18'}, {name:'steve', age:'18'}]
pAry[17]=cAry;
Таким образом, когда вам нужно лицо с 18 лет, вы получите индекс 17.
Ответ 7
Получить подходящие элементы и элементы с помощью методов find() и filter()
Если вы хотите, чтобы первый соответствовал одному элементу, используйте метод find(), который возвращает один объект.
Если вы хотите, чтобы все совпало, используйте метод filter(), который возвращает массив объектов.
let items = [{name:'charlie', age:'16'},
{name:'ben', age:'18'},
{name:'steve', age:'18'}]
let all = items.filter(item=> item.age==='18')
console.log(all);
let single = items.find(item=> item.age==='18')
console.log(single);