在我的网络应用程序中,我有一个对象,它是从服务器传递的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.parse()解析JSON。这创建了一个我可以使用以下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值访问特定的itemlist项目?
假设没有,将我的顶级itemlist对象转换为对象数组的最有效方法是什么,其中原始项的所有属性仍可通过点表示法访问,并且任何项目都可以通过其直接访问ID? (我知道每个嵌套项都有一个_id,但我不会提前知道结构的其余部分)。在将JSON对象转换为数组与将其保持原样并使用我的低效循环之间是否存在任何性能权衡?
非常感谢。
答案 0 :(得分:4)
为了按值定位某些内容,您必须遍历该对象并测试各个键的值。没有办法避免这种情况。
为了构建查找对象,您必须遍历整个对象一次,并从第一个对象收集值并将它们存储在第二个对象中。这是前期的密集型,但如果您必须通过您希望用作键的值重复查找内容,则等同于以后的节省。
所以问题是,你这样做了一次(你是在一个特定的JSON返回之后)或者在你的页面中反复发生这种情况(你在代码的A部分中使用了部分对象,然后是另一部分B部分中的对象的一部分,等等)?如果是前者,那么循环遍历整个对象并创建查找可能不值得增加开销。如果是后者,那么通过创建一种通过适当的密钥检索所需信息的更简单方法,您可能会从长远来看受益。
创建查找对象可能是这样的:
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']
};
}
答案 1 :(得分:2)
是的,这是另一个可以加载的库,但它可以让你的生活变得非常轻松。
var soughtKey = '4x3tC1oTBkyvbu43rQj0EQ==' ;
Enumerable.From(myJsonObject)
.Where('$._id.$binary == "' + soughtKey + '"')
.ForEach(doSomething);
function doSomething(obj) {
// do something with "obj";
}
在this jsFiddle中查看它。
要创建一个按ID索引的查找对象,也可以是一行代码:
var index = Enumerable.From(myJsonObject).ToObject("$._id.$binary", "$");
// later:
doSomething(index[soughtKey]);
答案 2 :(得分:0)
尝试http://goessner.net/articles/JsonPath/之类的内容。 XPath for JSON。
答案 3 :(得分:0)
尝试使用其ID记录每个项目?
var remember = {};
for (var ii = 0; ii < itemlist.length; ii++) {
var item = itemlist[ii];
remember[item._id.$binary] = item;
}