Каков наилучший способ найти некоторые элементы в массиве на основе значения свойства элемента? - PullRequest
2 голосов
/ 16 декабря 2009

У меня есть такой массив:

var anArray = [
    { name: "scala",  type: "a" },
    { name: "abc",    type: "b" },
    { name: "test",   type: "a" },
    { name: "ruby",   type: "c" },
    { name: "erlang", type: "a" },
];

Я хочу найти элементы на основе свойства элемента. В настоящее время я делаю это с помощью jQuery. как то так;

Array.prototype.find_by_key = function(key, value) {
    return $.grep(this, function(item){
        return (item[key] == value);
    });
}

var whatIHaveFound = anArray.find_by_key("type", "a"); // find items which the item property: "type" equals "a"

Есть ли лучший способ сделать это в JavaScript? или есть какой-то алгоритм, чтобы сделать это лучше и быстрее? когда массив имеет много элементов. это может быть очень медленно. есть идеи? спасибо.

Ответы [ 2 ]

2 голосов
/ 16 декабря 2009

Мудрые умы могут исправить меня, но я думаю, что вам придется повторять каждый раз (с более или менее похожими скоростями), если:

Вы знаете, что собираетесь повторить поиск и что некоторые ключи будут искать чаще, чем другие. Тогда вы можете сместить коллекцию так, чтобы она не была плоской, а была предварительно отсортирована в соответствии с вашими условиями. Таким образом, ваша коллекция станет:

var groupedByType = 
{"a":[{name:"scala"},{name:"test"}, {name:"erlang"}],  
{"b":[{name:"abc"}],  
{"c":[{name:"ruby"}]};  

В качестве альтернативы вы можете попытаться запоминать доступ к своей коллекции, например, после того, как вы выполнили поиск, вы запишете условия и результаты поиска, в этом случае сохраните его в кэше заметок как

["type","a"]:[
{ name: "scala",  type: "a" },  
{ name: "test",   type: "a" },  
{ name: "erlang", type: "a" }]

Плюсы и минусы этого: очень быстро получить доступ к ранее выполненным поискам, если базовые данные не изменились таким образом, который осуждает ваш кеш. С другой стороны, это означает, что вы должны контролировать доступ к данным (в этих случаях я люблю хранить свои данные внутри замыкания, так что мне нужно только выставлять мутаторы - что-то вроде облегченного ОО, но с большей защитой), и вы может оказаться более эффективным отбрасывать ваши кэшированные данные при их изменении, чем пытаться определить дельты, в зависимости от того, как структурированы ваши данные.

Что я хотел бы подчеркнуть прежде всего, так это абсолютно убедиться, что вам нужна какая-либо оптимизация. Этот подраздел достаточно быстрый? Можете ли вы довести свое приложение до скорости другим способом? Если вы пишете клиентскую поисковую систему или что-то в этом роде, вы, вероятно, захотите пойти немного дальше, чем просто определить, какой из итераторов jQuery самый быстрый.

1 голос
/ 05 января 2014

Вы можете использовать эту библиотеку JavaScript, DefiantJS (http://defiantjs.com),), с помощью которой вы можете фильтровать совпадения, используя XPath на структурах JSON. Чтобы поместить его в код JS:

var anArray = [
    { name: "scala",  type: "a" },
    { name: "abc",    type: "b" },
    { name: "test",   type: "a" },
    { name: "ruby",   type: "c" },
    { name: "erlang", type: "a" },
];.
res = JSON.search( anArray, '//*[type="a"]' );

console.log( res[0].name );
// scala

console.log( res.length );
// 3

Вот рабочая скрипка:
http://jsfiddle.net/hbi99/wM98Y/4/

DefiantJS расширяет глобальный объект методом «поиск» и возвращает массив совпадений (пустой массив, если совпадений не найдено). Вы можете попробовать запросы lib и XPath с помощью XPath Evaluator здесь:

http://www.defiantjs.com/#xpath_evaluator

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...