search что - JSON найти в JavaScript




примеры backbone (5)

(Вы не просматриваете «JSON», вы просматриваете массив - строка JSON уже была десериализована в графе объектов, в данном случае массиве.)

Некоторые варианты:

Использовать объект вместо массива

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

Скажите, что это ваши исходные данные:

[
    {"id": "one",   "pId": "foo1", "cId": "bar1"},
    {"id": "two",   "pId": "foo2", "cId": "bar2"},
    {"id": "three", "pId": "foo3", "cId": "bar3"}
]

Не могли бы вы сделать следующее?

{
    "one":   {"pId": "foo1", "cId": "bar1"},
    "two":   {"pId": "foo2", "cId": "bar2"},
    "three": {"pId": "foo3", "cId": "bar3"}
}

Тогда поиск соответствующей записи по идентификатору тривиален:

id = "one"; // Or whatever
var entry = objJsonResp[id];

... как обновляет его:

objJsonResp[id] = /* New value */;

... и удалив его:

delete objJsonResp[id];

Это использует тот факт, что в JavaScript вы можете индексировать объект, используя имя свойства в виде строки, - и эта строка может быть литералом, или она может исходить из переменной, как с указанным выше.

Вставка карты с индексом-индексом

(Неумная идея, предшествует вышеизложенному. Сохраняется по историческим причинам.)

Похоже, вам нужно, чтобы это было массивом, и в этом случае нет лучшего способа, чем поиск по массиву, если вы не хотите разместить на нем карту, что вы могли бы сделать, если у вас есть контроль над генерацией объект. Например, скажем, у вас это изначально:

[
    {"id": "one",   "pId": "foo1", "cId": "bar1"},
    {"id": "two",   "pId": "foo2", "cId": "bar2"},
    {"id": "three", "pId": "foo3", "cId": "bar3"}
]

Генерирующий код может предоставить карту id-to-index:

{
    "index": {
        "one": 0, "two": 1, "three": 2
    },
    "data": [
        {"id": "one",   "pId": "foo1", "cId": "bar1"},
        {"id": "two",   "pId": "foo2", "cId": "bar2"},
        {"id": "three", "pId": "foo3", "cId": "bar3"}
    ]
}

Тогда получение записи для id в переменной id тривиально:

var index = objJsonResp.index[id];
var obj = objJsonResp.data[index];

Это использует тот факт, что вы можете индексировать объекты, используя имена свойств.

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

Но если вы не контролируете создание объекта или обновляете карту идентификаторов-индексов, слишком много проблем с обслуживанием кода и / или, то вам придется выполнять поиск грубой силы.

Поиск грубой силы (исправлено)

Немного OT (хотя вы спрашивали, есть ли лучший способ :-)), но ваш код для циклического перемещения массива неверен. Подробности здесь , но вы не можете использовать for..in для циклического for..in индексов массива (или, вернее, если вы это сделаете, вам нужно сделать особые усилия); for..in перебирает свойства объекта , а не индексы массива . Ваш лучший выбор с не разреженным массивом (и ваш не-разреженный) - это стандартный старомодный цикл:

var k;
for (k = 0; k < someArray.length; ++k) { /* ... */ }

или

var k;
for (k = someArray.length - 1; k >= 0; --k) { /* ... */ }

Какой бы вы ни предпочли (последнее не всегда быстрее во всех реализациях, что противоречит интуиции, но мы здесь). (С редким массивом, вы можете использовать для for..in но снова for..in особые усилия, чтобы избежать ловушек, больше в статье, приведенной выше).

Использование for..in в массиве, похоже, работает в простых случаях, поскольку массивы имеют свойства для каждого из своих индексов, а их единственные другие свойства по умолчанию ( length и их методы) отмечены как неперечислимые. Но он прерывается, как только вы устанавливаете (или фреймворк) любые другие свойства объекта массива (что совершенно верно, массивы - это просто объекты с некоторой особой обработкой вокруг свойства length ).

Есть ли лучший способ, кроме цикла, найти данные в JSON ? Это для редактирования и удаления.

for(var k in objJsonResp) {
  if (objJsonResp[k].txtId == id) {
    if (action == 'delete') {
      objJsonResp.splice(k,1);
    } else {
      objJsonResp[k] = newVal;
    }
    break;
  }
}

Данные упорядочены как список карт. Подобно:

[
  {id:value, pId:value, cId:value,...},
  {id:value, pId:value, cId:value,...},
  ...
]

Я столкнулся с этой проблемой для сложной модели с несколькими вложенными объектами. Хорошим примером того, что я искал, было бы так: Допустим, у вас есть поляроид. И эта картина затем помещается в багажник автомобиля. Автомобиль находится внутри большого ящика. Ящик находится в трюме большого корабля с множеством других ящиков. Мне пришлось искать трюм, смотреть в ящики, проверять багажник, а затем искать существующую картину меня.

Я не мог найти никаких хороших решений в Интернете, и использование .filter() работает только с массивами. Большинство решений предложили просто проверить, существует ли model["yourpicture"] . Это было очень нежелательно, потому что, например, это только обыскало трюм корабля, и мне нужен был способ получить их дальше от кроличьей дыры.

Это рекурсивное решение, которое я сделал. В комментариях я подтвердил от TJ Crowder, что потребуется рекурсивная версия. Я думал, что поделюсь им, если кто-нибудь столкнется с подобной сложной ситуацией.

function ContainsKeyValue( obj, key, value ){
    if( obj[key] === value ) return true;
    for( all in obj )
    {
        if( obj[all] != null && obj[all][key] === value ){
            return true;
        }
        if( typeof obj[all] == "object" && obj[all]!= null ){
            var found = ContainsKeyValue( obj[all], key, value );
            if( found == true ) return true;
        }
    }
    return false;
}

Это будет начинаться с заданного объекта внутри графа и перезаписывать любые найденные объекты. Я использую его так:

var liveData = [];
for( var items in viewmodel.Crates )
{
    if( ContainsKeyValue( viewmodel.Crates[items], "PictureId", 6 ) === true )
    {
        liveData.push( viewmodel.Crates[items] );
    }
}

Который приведет к созданию массива ящиков, содержащих мою картину.


Если вы делаете это более чем в одном месте в своем приложении, имеет смысл использовать базу данных JSON на стороне клиента, потому что создание пользовательских функций поиска является беспорядочным и менее удобным, чем альтернатива.

Ознакомьтесь с ForerunnerDB, который предоставляет вам очень мощную систему базы данных JSON на стороне клиента и включает в себя очень простой язык запросов, который поможет вам выполнить именно то, что вы ищете:

// Create a new instance of ForerunnerDB and then ask for a database
var fdb = new ForerunnerDB(),
    db = fdb.db('myTestDatabase'),
    coll;

// Create our new collection (like a MySQL table) and change the default
// primary key from "_id" to "id"
coll = db.collection('myCollection', {primaryKey: 'id'});

// Insert our records into the collection
coll.insert([
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]);

// Search the collection for the string "my nam" as a case insensitive
// regular expression - this search will match all records because every
// name field has the text "my Nam" in it
var searchResultArray = coll.find({
    name: /my nam/i
});

console.log(searchResultArray);

/* Outputs
[
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]
*/

Отказ от ответственности: Я разработчик ForerunnerDB.


Zapping - вы можете использовать эту javascript lib; DefiantJS. Нет необходимости реструктурировать данные JSON в объекты, чтобы облегчить поиск. Вместо этого вы можете искать структуру JSON с выражением XPath следующим образом:

    var data = [
   {
      "id": "one",
      "pId": "foo1",
      "cId": "bar1"
   },
   {
      "id": "two",
      "pId": "foo2",
      "cId": "bar2"
   },
   {
      "id": "three",
      "pId": "foo3",
      "cId": "bar3"
   }
],
res = JSON.search( data, '//*[id="one"]' );

console.log( res[0].cId );
// 'bar1'

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

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

XPath - это, как вы знаете, стандартизованный язык запросов.


Я лично использую Underscore.js для манипулирования объектами и массивами:

myObject = _.omit(myObject, 'regex');






javascript json search