admin管理员组文章数量:1245133
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.
Mocked up JSON Object (the ids
property could be at much deeper property locations).
{
"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.
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?
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.
Mocked up JSON Object (the ids
property could be at much deeper property locations).
{
"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.
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?
5 Answers
Reset to default 7If the data was actually a JSON string, and not a JavaScript object, you could have something like:
// 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.parse method.
what you have is fine, but this is a little shorter and uses the .map function:
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);
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.
- Change the
if {...} traverse
toif {...} 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 pletely on the context and whether or not you can make this change!
Sorry I'm not of more help!
Assuming ES5 is available natively or via a 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;
}, []);
}
Using object-scan this bees very simple. Note that you can easily specify what is targeted (in this case **.ids[*].id
)
// const objectScan = require('object-scan');
const data = { 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' }] } };
const findIds = (input) => objectScan(['**.ids[*].id'], { rtn: 'value' })(input);
console.log(findIds(data));
/* => [ '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' ]
*/
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>
Disclaimer: I'm the author of object-scan
本文标签:
版权声明:本文标题:javascript - How to traverse JSON object locating particular property and pushing its contents to array? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740184076a2237881.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论