我有一个包含一些json数据的变量json。我正在尝试检索该数据的特定部分。我可以使用索引做这样所示:从json获取特定数据
var newdata = json[listid].Taxonomies[0];
不过,我希望能够用一个名字来检索数据... 比如我想要得到的数据,其中
json[listid].Taxonomies[?].InternalName = 'ABC'
,我不知道'?'的价值
有没有一种方法可以做到这一点,而不需要在分类法上做每个循环?
我有一个包含一些json数据的变量json。我正在尝试检索该数据的特定部分。我可以使用索引做这样所示:从json获取特定数据
var newdata = json[listid].Taxonomies[0];
不过,我希望能够用一个名字来检索数据... 比如我想要得到的数据,其中
json[listid].Taxonomies[?].InternalName = 'ABC'
,我不知道'?'的价值
有没有一种方法可以做到这一点,而不需要在分类法上做每个循环?
有人建议linqjs,如果你需要大量的JSON查询的可能行。但是,对于此问题,您可以使用Array.filter来指定要查找的项目。显然,引擎盖下还有一个循环。
var matches = json[listid].Taxonomies.filter(function(obj) {
return obj.InternalName === "ABC";
})
console.log(matches[0]);
请注意,如果你担心性能,你应该使用一个对象,而不是为你的数据表示一个数组,你可以通过你会被被搜索的属性键它。
如果我需要在数组上搜索多次,我使用的一个有用函数如下。这将数组转换为可以无循环访问的映射。如果您担心性能问题,只需以相应的格式生成数据即可。
/**
* Creates a map by the given property to allow fast searches
* @param {object[]} arr Array that we want to create a map from
* @param {string} keyProp The property to key by
* @param {boolean} [allowDuplicates] If this is true, the value
* of each key in the returned object will be an array with
* all matches
* @return A map keyed by the requested property. If the parameter
* allowDuplicates is falsy, key property collisions will
* overwrite the previous value. If the allowDuplicates is true,
* the map will have as its value an array of objects for the given key
*
* Example: Given the following array: arr=[{a:1, b:2}, {a:1, b:3}, {a:3, b:4)]
* The call to mapFromArray(arr, 'a') returns the following
* { 1: {a:1, b:3}, 3: {a:3, b:4} }
* Notice that {a:1,b:2} is not in the returned map because it has the
* same value in the key property 'a' as {a:1, b:3}, which wins out
* since it's later.
*
* Calling mapFromArray(arr, 'a', true) returns the following
* { 1: [{a:1, b:2}, {a:1, b:3}], 3: [{a:3, b:4}] }
*/
function mapFromArray(arr, keyProp, allowDuplicates) {
var map = {};
for (var i = 0, ln = arr.length; i < ln; i++) {
if (!allowDuplicates) {
// No duplicates allowed, may be overwriting an existing value
map[arr[i][keyProp]] = arr[i];
} else {
// Duplicates are allowed, create array of matching objects
// Ext.Array.push creates a one item array if its argument is
// not already an array, otherwise, it pushes and returns the array
map[arr[i][keyProp]] = Ext.Array.push(map[arr[i][keyProp]], arr[i]);
}
}
return map;
}
所以说你想搜索的分类与“ABC”'DEF“GHI”之一的InternalName
,你会做以下几点:
var map = mapFromArray(json[listid].Taxonomies, "InternalName");
var ABC = map['ABC'], DEF = map['DEF'], GHI = map['GHI'];
var newdata = json[listid].Taxonomies.filter(function(el){
return el.InternalName === "ABC";
})[0];
应该覆盖像这样的对象的第一次出现。如果你想要一个包含所有事件的数组,你可以在最后删除[0]
。
请注意,我假设一个单一的嵌套级别,因为那是如何问题措辞。如果您需要在任意深度的数据结构中查找属性,这里的其他一些库可能更有意义。
这不能没有循环就可以完成,但存在隐藏循环的库。
例如,使用JSPath你可以找到InternalName
财产的每个实例,无论它是多么深的嵌套:
> var json = { 1: { Taxonomies: [ { InternalName: 'ABC' } ] }}
> JSPath.apply('..InternalName', json);
["ABC"]
想到的是一样的东西linqjs(http://linqjs.codeplex.com/)的第一件事。以下是给出您输入的示例。
var jsonArray = [
{ "listid": 1,
Taxaonomies:
[
{ "id": 100, "InternalName": "d_linq" },
{ "id": 200, "InternalName": "fred" }
]
},
{ "listid": 2,
Taxaonomies:
[
{ "id": 100, "InternalName": "asdf" },
{ "id": 200, "InternalName": "qwer" }
]
}
];
var queryResult = Enumerable.From(jsonArray)
.Where(function (x) {
return Enumerable.From(x.Taxaonomies).Any(function (y) { return y.InternalName == "fred" })
})
.ToArray();
console.log(queryResult);
yeuch。这怎么比JSPath更简单或者只是使用JS的内置枚举和过滤函数进行迭代? – Alnitak
linqjs比我所演示的更加强大,我几乎可以保证用linqjs做比使用本地js更复杂的东西会更容易。 PLUS,linqjs很容易学习,如果你已经熟悉.NET中的linq。 :) –
您可以使用jQuery JavaScript库将JSON解析为一个对象。从那里你可以使用点语法访问属性。
http://api.jquery.com/jQuery.parseJSON/
var obj = jQuery.parseJSON('{"name":"Bob"}');
alert(obj.name === "Bob");
没有循环?有趣。 –
json [listid] .Taxonomies [var] ??? –
基于我知道的内部名称的值。 – BlueBird