Поиск объекта JavaScript
У меня есть JavaScript-объект вроде этого:
[{
name : "soccer",
elems : [
{name : "FC Barcelona"},
{name : "Liverpool FC"}
]
},
{
name : "basketball",
elems : [
{name : "Dallas Mavericks"}
]
}]
Теперь я хочу выполнить поиск по этому объекту JavaScript в браузере. Поиск "FC" должен дать мне что-то вроде этого:
[
{name : "FC Barcelona"},
{name : "Liverpool FC"}
]
Как это сделать быстро? Существуют ли для этого библиотеки JavaScript?
Ответы
Ответ 1
Вам может понравиться использовать jLinq (личный проект)
http://Hugoware.net/Projects/jLinq
Работает как LINQ, но для JSON, и позволяет вам расширять его и изменять его, как вы хотите. Уже существует набор готовых методов для проверки значений и диапазонов.
Ответ 2
Хотя вы можете сделать это в прямом JavaScript, underscore.js - хорошая библиотека для обработки этого материала. Вероятно, вы могли бы это сделать с "выщипыванием" и "каждым".
Хорошая вещь о underscore.js заключается в том, что она использует встроенные вызовы браузера, когда они существуют.
Ответ 3
Увидев, что единственные полезные ответы касаются сторонних библиотек - вот ваше собственное решение для JavaScript. Для тех, кто хочет только несколько строк кода, а не стек:
Функция:
Array.prototype.findValue = function(name, value){
var array = map(this, function(v,i){
var haystack = v[name];
var needle = new RegExp(value);
// check for string in haystack
// return the matched item if true, or null otherwise
return needle.test(haystack) ? v : null;
});
return array;
}
Нативная функция .map()
:
map = function(array, mapFunction) {
var newArray = new Array(array.length);
for(var i = 0; i < array.length; i++) {
newArray[i] = mapFunction(array[i]);
}
return newArray;
}
Ваш объект:
(снято с вашего опубликованного abject):
myObject = {
name : "soccer",
elems : [
{name : "FC Barcelona"},
{name : "Liverpool FC"}
]
},
{
name : "basketball",
elems : [
{name : "Dallas Mavericks"}
]
}
Для использования:
(Это приведет к поиску вашего массива myObject.elems для соответствия имени 'FC')
var matched = myObject.elems.findValue('name', 'FC');
console.log(matched);
Результат - проверьте консоль:
[Object, Object, findValue: function]
0: Object
name: "FC Barcelona"
__proto__: Object
1: Object
name: "Liverpool FC"
__proto__: Object
length: 2
__proto__: Array[0]
Ответ 4
Попробуйте jOrder. http://github.com/danstocker/jorder
Он оптимизирован для быстрого поиска и сортировки O (logn) на больших (тысячи строк) таблицах в JS.
В отличие от итераций массива, в основе которых лежит большинство ответов, jOrder использует индексы для фильтрации данных. Как раз для того, чтобы дать вам идею, поиск по свободному тексту в таблице из 1000 строк завершается примерно в 100 раз быстрее, чем итерация. Чем больше таблица, тем лучше вы получите.
Однако jOrder не может обрабатывать формат ваших данных образца. Но если вы переформатируете его так:
var teams =
[
{ sport : "soccer", team: "FC Barcelona" },
{ sport : "soccer", team: "Liverpool FC" },
{ sport : "basketball", team : "Dallas Mavericks"}
]
Вы можете получить желаемые результаты, предварительно установив таблицу jOrder:
var table = jOrder(teams)
.index('teams', ['team'], { grouped: true, ordered: true, type: jOrder.text });
И затем выполните поиск по нему:
var hits = table.where([{ team: 'FC' }], { mode: jOrder.startof });
И вы получите точно две строки, которые вам нужны. Что это.
Ответ 5
Простым способом сделать это просто перебрать все свойства объекта и применить к ним тестовую функцию (в этом случае value.contains("FC")
).
Если вы хотите, чтобы он работал быстрее, вам нужно было либо реализовать какое-то кэширование (которое можно было бы легко заполнить в фоновом режиме перед любыми запросами), либо, возможно, предусмотреть результат различных популярных тестовых функций.
Ответ 6
Вы можете сделать это с помощью регулярных выражений, выполненных против сериализованной строки JSON:
var jsonString = "[{ name : \"soccer\", elems : [ {name : \"FC Barcelona\"}"
+", {name : \"Liverpool FC\"}]},{name : \"basketball\",elems : ["
+"{name : \"Dallas Mavericks\"} ]}]";
var pattern = /\s*([\w\d_]+)\s*:\s*((\"[^\"]*(your pattern here)[^\"]*\")|(\'[^\']*(your pattern here)[^\']*\'))\s*/g;
var foundItems = [];
var match;
while(match = pattern.exec(jsonString)){
foundItems.push(match[0]);
}
var foundJSON = "[{" + foundItems.join("}, {") + "}]";
var foundArray = eval(foundJSON);
Я не тестировал эту часть цикла, но Regex, похоже, хорошо работает для меня с простыми тестами в firebug.
Ответ 7
Что касается AngularJS, вы можете сделать это:
var item = "scope-ng-model";
(angular.element('form[name="myForm"]').scope())[item] = newVal;