Given a JSON structure
var json = {
'a': {
'a1': ['a1a', 'a1b', 'a1c'],
'a2': ['a2a', 'a2b'],
'a3': []
},
'b': {
'b1': ['b1a', 'b1b', 'b1c', 'b1d'],
'b2': ['b2a', 'b2b'],
},
'c': ['c1', 'c2'],
'd': {
'd1': ['d1a', 'd1b', 'd1c'],
'd2': []
},
'e': ['e1', 'e2'],
'f': [
'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10'
]
};
Using Javascript how can I traverse this to yield an array of all keys and values? In other words, without simply keeping an external store and append to it as I traverse, how can I return an array of the entire set of node keys and values?
For example in Python I might make use of a generator. So perhaps I should ask, how can I use a generator in Javascript?
Javascript example with jQuery:
function traverse(jsonObj) {
if( typeof jsonObj == "object" ) {
$.each(jsonObj, function(k,v) {
traverse(v);
});
}
else {
// how can I yield this value instead?
console.log(jsonObj)
}
}
Where my expected output would be an array of all keys and values:
['a', 'a1', 'a1a', 'a1b', 'a1c', 'a2', 'a2a', 'a2b'] // ... and so on
ECMAScript 6 has generators. So you can write the function as
function *traverse(value) {
if (typeof value === "object") {
var isArray = Array.isArray(value);
for (var prop in value) {
if (!isArray) yield prop;
yield* traverse(value[prop]);
}
}
else {
yield value;
}
}
And use it as:
var obj = {
'a': {
'a1': ['a1a', 'a1b', 'a1c'],
'a2': ['a2a', 'a2b'],
'a3': []
}
};
console.log(Array.from(traverse(obj)));
But it's also not much different without native generators:
function traverse(value, result) {
result = result || [];
if (typeof value === "object") {
var isArray = Array.isArray(value);
for (var prop in value) {
if (!isArray) result.push(prop);
traverse(value[prop], result);
}
}
else {
result.push(value);
}
return result;
}
console.log(traverse(obj));