Поиск объекта 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;