(您不是在搜索“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找到相关条目非常简单:
id = "one"; // Or whatever
var entry = objJsonResp[id];
...正在更新它:
objJsonResp[id] = ;
...并将其移除:
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-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];
这利用了您可以使用属性名称对对象进行索引的事实。
当然,如果您这样做,您必须在修改数组时更新映射,这可能会成为一个维护问题。
但是,如果您无法控制对象的生成,或者更新id-to-index映射太多代码和/或维护问题,则必须进行暴力搜索。
暴力搜索(已更正)
有点 OT(尽管您确实问是否有更好的方法 :-)),但是您循环遍历数组的代码是不正确的。 Details here,但是您不能使用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
在简单情况下似乎是有效的,因为数组具有每个索引的属性,并且它们的唯一其他默认属性(
length
和它们的方法)被标记为不可枚举。 但是,只要您设置(或框架设置)数组对象上的任何其他属性(这是完全有效的;数组只是具有一些围绕
length
属性的特殊处理的对象),它就会中断。