Вложенный объект JSON против массива Javascript - PullRequest
2 голосов
/ 06 октября 2011

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

{
  "_id": {
    "$binary": "4x3tC1oTBkyvbu43rQj0EQ==",
    "$type": "03"
  },
  "title": "Sony FW31 Lit 973.pdf",
  "tags": [
    {
      "category": "Machine",
      "text": "Cold Planers"
    },
    {
      "category": "Attachments",
      "text": "Blades"
    }
  ]
}
,
{
  "_id": {
    "$binary": "s/Svg2CjSUWB1QGJ7e3QeA==",
    "$type": "03"
  },
  "title": "Sony FW31 Lit 974.pdf",
  "tags": [
    {
      "category": "Machine",
      "text": "Cold Planers"
    },
    {
      "category": "Attachments",
      "text": "Blades"
    }
  ]
},... and lots more items...

В строке JSON могут быть тысячи объектов.Я могу с радостью проанализировать JSON с помощью JSON.parse ().Это создает объект, который я могу перебрать, используя следующий javascript:

var soughtKey='4x3tC1oTBkyvbu43rQj0EQ==';
for (var ii = 0; ii < itemlist.length; ii++) {
    var item = itemlist[ii];
    if (item._id$binary==soughtKey){
        doSomething(item);
    }
}

Это кажется довольно неэффективным.Я бы предпочел сделать это:

doSomething(itemlist[soughtKey]);

Но предположительно, чтобы сделать это, мне нужно было бы преобразовать мой объект верхнего уровня в какой-то массив индексируемых по ключу массивов?Я предполагаю, что нет никакого способа получить доступ к определенным элементам списка элементов, используя их значения идентификатора?

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

Большое спасибо.

Ответы [ 4 ]

4 голосов
/ 06 октября 2011

Чтобы найти что-то по значению, вы должны перебрать объект и проверить значения по отдельным ключам. Этого не избежать.

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

Таким образом, вопрос в том, делаете ли вы это один раз (вы после определенной части возврата JSON), или это происходит на вашей странице неоднократно (вы используете часть объекта в разделе A кода, а затем другую часть объекта в разделе Б и т. д.)? Если первое, вероятно, не стоит дополнительных накладных расходов, чтобы пройтись по всему объекту и создать поиск. Если последнее, то вы, вероятно, выиграете в долгосрочной перспективе, создав более простой способ получения нужной информации по соответствующим ключам.

Создание вашего поискового объекта может выглядеть примерно так:

var byIds = {};

for (var ii = 0, l = items.length; ii < l; ++ii) {
  var item = items[ii];

  byIds[item._id.$binary] = {
    'title': item['title'],
    'tags': item['tags']
  };
}
2 голосов
/ 06 октября 2011

Вы можете попробовать linq.js ( ссылка ), если хотите.

Да, это еще одна библиотека, которую можно загрузить, но впоследствии она может упростить вашу жизнь с такими вещами.

var soughtKey = '4x3tC1oTBkyvbu43rQj0EQ==' ;

Enumerable.From(myJsonObject)
          .Where('$._id.$binary == "' + soughtKey + '"')
          .ForEach(doSomething);

function doSomething(obj) {
  // do something with "obj";
}

Посмотрите, как это работает в this jsFiddle .


Для создания объекта поиска, индексируемого по идентификатору, также будет использоваться одна строка:

var index = Enumerable.From(myJsonObject).ToObject("$._id.$binary", "$");

// later:
doSomething(index[soughtKey]);
0 голосов
/ 06 октября 2011

Попробуйте записать каждый элемент с его идентификатором?

var remember = {};

for (var ii = 0; ii < itemlist.length; ii++) {
    var item = itemlist[ii];
    remember[item._id.$binary] = item;
}
0 голосов
/ 06 октября 2011

Попробуйте что-то вроде http://goessner.net/articles/JsonPath/. XPath для JSON.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...