javascript 如何遍历 JSON 对象定位特定属性并将其内容推送到数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15993038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to traverse JSON object locating particular property and pushing its contents to array?
提问by ahsteele
I am working with a JSON object which can have a property ids
at any leaf. I want to traverse the object and find all of the instances of the ids
property and store each id in a collection.
我正在使用一个 JSON 对象,它可以ids
在任何叶子上都有一个属性。我想遍历对象并找到该ids
属性的所有实例并将每个 id 存储在一个集合中。
Mocked up JSON Object (the ids
property could be at much deeper property locations).
模拟 JSON 对象(该ids
属性可能位于更深的属性位置)。
{
"id": "b38a683d-3fb6-408f-9ef6-f4b853ed1193",
"foo": {
"ids": [
{
"id": "bd0bf3bd-d6b9-4706-bfcb-9c867e47b881"
},
{
"id": "d1cc529d-d5d2-4460-b2bb-acf24a7c5999"
},
{
"id": "b68d0c8c-548e-472f-9b01-f25d4b199a71"
}
],
"baz": "super"
},
"bar": {
"ids": [
{
"id": "bd0bf3bd-d6b9-4706-bfcb-9c867e47b881"
},
{
"id": "d1cc529d-d5d2-4460-b2bb-acf24a7c5999"
},
{
"id": "b68d0c8c-548e-472f-9b01-f25d4b199a71"
}
]
}
}
I am using the following code to traverse the above JSON.
我正在使用以下代码遍历上述 JSON。
var jsonFile = require('./file_test.json'); // the above in my local directory
function traverse(obj, ids) {
for (var prop in obj) {
if (typeof obj[prop] == "object" && obj[prop]) {
if (prop == 'ids') {
for (var i = obj[prop].length - 1; i >= 0; i--) {
ids.push(obj[prop][i]._id);
};
}
traverse(obj[prop], ids);
}
}
}
var ids = new Array();
traverse(jsonFile, ids);
console.log('ids', ids);
The above nets the following:
以上网络如下:
ids
[
'b68d0c8c-548e-472f-9b01-f25d4b199a71',
'd1cc529d-d5d2-4460-b2bb-acf24a7c5999',
'bd0bf3bd-d6b9-4706-bfcb-9c867e47b881',
'b68d0c8c-548e-472f-9b01-f25d4b199a71',
'd1cc529d-d5d2-4460-b2bb-acf24a7c5999',
'bd0bf3bd-d6b9-4706-bfcb-9c867e47b881'
]
While my code works I am not convinced that I am doing this the most efficient or best way. Is there a better way to find all instances of the ids
property? Perhaps without passing in an array but returning one? Or setting up for a callback with an ids
array?
虽然我的代码有效,但我不相信我这样做是最有效或最好的方式。有没有更好的方法来查找ids
属性的所有实例?也许不传入数组但返回一个?或者使用ids
数组设置回调?
回答by ZER0
If the data was actually a JSON string, and not a JavaScript object, you could have something like:
如果数据实际上是一个 JSON 字符串,而不是一个 JavaScript 对象,你可以有这样的东西:
// assuming `json` is the data string
var ids = [];
var data = JSON.parse(json, function(key, value) {
if (key === "id")
ids.push(value);
return value;
});
See reviver
on JSON.parsemethod.
请参见reviver
上JSON.parse方法。
回答by phillro
what you have is fine, but this is a little shorter and uses the .map function:
你所拥有的很好,但这有点短,并且使用了 .map 函数:
var jsonFile = require('./file_test.json'); // the above in my local directory
function traverse(obj) {
var ids = [];
for (var prop in obj) {
if (typeof obj[prop] == "object" && obj[prop]) {
if (prop == 'ids') {
ids = obj[prop].map(function(elem){
return elem.id;
})
}
ids =ids.concat(traverse(obj[prop]));
}
}
return ids;
}
var ids =traverse(jsonFile);
console.log('ids', ids);
回答by ryaanwells
What you're basically trying to do is a tree search of this JSON object, am I right? So if we assume that ids
is always a leaf then we do not need to traverse
those nodes as we know they are at the leaf and will contain what we want.
您基本上要做的是对这个 JSON 对象进行树搜索,对吗?因此,如果我们假设它ids
总是一片叶子,那么我们就不需要traverse
那些节点,因为我们知道它们在叶子上并且将包含我们想要的东西。
- Change the
if {...} traverse
toif {...} else {traverse}
- 更改
if {...} traverse
为if {...} else {traverse}
If it is possible to change the data structure of ids
to a list of strings instead of a list of objects then you will be able to save the iteration over the array and just merge it onto the ids
array passed in, but it depends completely on the context and whether or not you can make this change!
如果可以将数据结构更改ids
为字符串列表而不是对象列表,那么您将能够保存对数组的迭代并将其合并到ids
传入的数组中,但这完全取决于上下文以及您是否可以进行此更改!
Sorry I'm not of more help!
对不起,我没有更多帮助!
回答by Brad Harris
Assuming ES5 is available natively or via a shim:
假设 ES5 可在本机或通过shim 使用:
function gimmeIds(obj) {
return Object.keys(obj||{})
.reduce(function(ids, key) {
if(key === 'ids') {
return ids.concat(obj[key].map(function(idObj) {
return idObj.id;
}));
}
if(obj[key] && typeof obj[key] == 'object') {
return ids.concat(gimmeIds(obj[key]));
}
return ids;
}, []);
}