How to traverse JSON object locating particular property and pushing its contents to array?
Solution 1
If 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.
Solution 2
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);
ahsteele
Professional success influenced by practical academics has shaped my outlook on software development. I have never stopped learning and am always interested in refining my development processes. For me it is not just the programming, all aspects of software development excite me.
Updated on June 07, 2022Comments
-
ahsteele almost 2 years
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 theids
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 anids
array?