JSON находят в JavaScript

Существует ли лучший путь кроме цикличного выполнения для нахождения данных в 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,...},
  ...
]

59
задан MrIsaacs 27 January 2016 в 20:16
поделиться

2 ответа

(Вы ищете не через "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, приведенным выше.

Помещение в ID-индексную карту

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

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

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

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

{
    "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];

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

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

Но если вы не контролируете генерацию объекта, или обновление карты ids-to-indexes - это слишком большая проблема с кодом и/или обслуживанием, то вам придется выполнить поиск методом перебора.

Brute Force Search (исправлен)

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

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

или

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

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

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

.
186
ответ дан 24 November 2019 в 18:00
поделиться

Если JSON-данные в вашем массиве каким-то образом отсортированы, то вы можете реализовать различные виды поиска. Однако, если Вы имеете дело не с большим количеством данных, то, скорее всего, у Вас все будет в порядке с операцией O(n) здесь (как и у Вас). Все остальное, скорее всего, будет чрезмерным.

.
0
ответ дан 24 November 2019 в 18:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: