2009-12-16 1 views
2

У меня есть массив как это:Каков наилучший способ найти некоторые элементы в массиве на основе значения свойства элемента?

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

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

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

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

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

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

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

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

+0

большое спасибо. очень всеобъемлющий спасибо. – www

1

Вы можете использовать эту javascript lib, 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

Смежные вопросы