简体   繁体   English

JSON嵌套对象与Javascript数组

[英]JSON nested object versus Javascript array

In my web app I have an object which is built from a JSON string passed from a server. 在我的Web应用程序中,我有一个根据从服务器传递的JSON字符串构建的对象。 A typical JSON string might look like this: 典型的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...

There might be thousands of objects in the JSON string. JSON字符串中可能有数千个对象。 I can happily parse the JSON using JSON.parse(). 我可以使用JSON.parse()快乐地解析JSON。 This creates an object that I can iterate over using the following javascript: 这将创建一个对象,我可以使用以下javascript进行迭代:

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

This seems rather inefficient. 这似乎效率很低。 I'd rather do this: 我宁愿这样做:

doSomething(itemlist[soughtKey]);

But presumably to do this I'd need to convert my top-level object into some sort of key-indexable array? 但是大概要做到这一点,我需要将我的顶级对象转换成某种可索引的键数组吗? I assume there is no way to gain access to specific itemlist items using their id values? 我假设没有办法使用其ID值来访问特定项列表项?

Assuming not, what is the most efficient way to convert my top-level itemlist object into an array of objects where all the properties of the original items are still accessible via the dot notation, and any item can be directly accessed via its id? 假设不是,将顶级项目列表对象转换为对象数组的最有效方法是什么,在该对象数组中仍可以通过点符号访问原始项目的所有属性,并且可以通过其ID直接访问任何项目? (I know each nested item will have an _id, but I won't know the rest of the structure in advance). (我知道每个嵌套项目都会有一个_id,但我不会事先知道结构的其余部分)。 And are there any performance trade-offs between converting the JSON object to the array versus leaving it as-is and using my inefficient loop? 在将JSON对象转换为数组与按原样保留它以及使用效率低下的循环之间是否存在性能折衷?

Thanks very much. 非常感谢。

In order to locate something by value you have to loop over the object and test the values at the individual keys. 为了通过值定位某物,您必须在对象上循环并测试各个键上的值。 There's no way to avoid this. 无法避免这种情况。

In order to build a lookup object you have to loop over the entire object one time and collect values from the first object and store them in the second object. 为了构建查找对象,您必须循环遍历整个对象一次,并从第一个对象收集值并将它们存储在第二个对象中。 This is intensive up front, but will equate to savings later if you have to repeatedly find things by the values you'd like to use as keys. 这是预先准备的工作,但是如果您必须根据要用作键的值重复查找内容,则等于以后节省了费用。

So the question is, do you do this once (you're after a specific piece of the JSON return) or does this happen repeatedly in your page (you use part of the object in section A of the code, then another part of the object in section B, etc)? 因此,问题是,您执行一次此操作(是在特定的JSON返回之后)还是在页面中重复发生(您使用代码A节中的对象的一部分,然后是代码的另一部分)? B部分中的对象,等等)? If the former, it's probably not worth the added overhead to loop through the entire object and create a lookup. 如果是前者,则不值得在整个对象之间循环并创建查找而增加的开销。 If the latter, then you'll probably benefit in the long run by creating an easier way to retrieve your desired information by appropriate keys. 如果是后者,那么从长远来看,通过使用适当的密钥创建更轻松的方法来检索所需信息的方法,您可能会从中受益。

Creating your lookup object might go something like this: 创建您的查找对象可能如下所示:

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']
  };
}

You could give linq.js ( reference ) a try, if you want. 如果需要,您可以尝试linq.js参考 )。

Yes, it's yet another library to load, but it can make your life very easy afterwards with things like this. 是的,它是另一个要加载的库,但是通过这种事情,以后可以使您的生活变得很轻松。

var soughtKey = '4x3tC1oTBkyvbu43rQj0EQ==' ;

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

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

See it working in this jsFiddle . 看到它在此jsFiddle中工作。


To create an look-up object, indexed by ID, would be a one-liner as well: 要创建一个按ID索引的查找对象,也是一种方法:

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

// later:
doSomething(index[soughtKey]);

Try something like http://goessner.net/articles/JsonPath/ . 尝试类似http://goessner.net/articles/JsonPath/的方法 XPath for JSON. JSON的XPath。

Try record each item with its id? 尝试记录每个项目的ID?

var remember = {};

for (var ii = 0; ii < itemlist.length; ii++) {
    var item = itemlist[ii];
    remember[item._id.$binary] = item;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM