I am working to get values from deeply nested object. The data and expected output are below. I got this data like below from request of API.
I have to use this script at Google Apps Script. So please note I cannot use ECMAScript6.
Object
var obj = {
"key1": [
{
"key2": [
{
"key3": {
"key4": {
"key5": [
{
"key6": "value6"
},
{},
{
"key7": {
"key8": "value8"
}
}
]
}
}
},
{
"key3": {
"key4": {
"key5": [
{
"key6": "value6"
},
{
"key7": {
"key8": "value8"
}
},
{}
]
}
}
},
{
"key3": {
"key5": "value5"
}
}
]
},
{
"key2": [
{
"key3": {
"key4": {
"key5": [
{
"key6": "value6"
},
{
"key7": {
"key8": "value8"
}
}
]
}
}
},
{
"key3": {
"key4": {
"key5": [
{
"key6": "value6"
},
{},
{
"key7": {
"key8": "value8"
}
},
{}
]
}
}
},
{
"key3": {
"key5": "value5"
}
}
]
}
]
};
Expected output
I want values of "key8".
value8
value8
value8
value8
My current script
for (var i in obj.key1) {
for (var j in obj.key1[i].key2) {
for (var k in obj.key1[i].key2[j].key3.key4.key5[k]) {
Logger.log(obj.key1[i].key2[j].key3.key4.key5[k].key7.key8)
}
}
}
Error message
TypeError: Cannot read property "key5" from undefined.
This error is at
for (var k in json.key1[i].key2[j].key3.key4.key5[k]) {
My questions are
- What is reason of error?
- How modify should I my script to get values of "key8"?
Updated
I got 2 solutions of my question.
One is
var result = [];
for (var i in obj.key1) {
for (var j in obj.key1[i].key2){
if (obj.key1[i].key2[j].key3.key4) {
for (var k in obj.key1[i].key2[j].key3.key4.key5) {
if (obj.key1[i].key2[j].key3.key4.key5[k].key7) {
result.push(obj.key1[i].key2[j].key3.key4.key5[k].key7.key8);
}
}
} else {
continue;
}
}
}
Logger.log(result) // >>> [value8, value8, value8, value8]
https://jsfiddle.net/Lxa8tsfb/
Another is
var result = function () {
var result = [];
(function traverse(obj) {
if (Array.isArray(obj)) {
obj.forEach(traverse);
} else if (typeof obj === 'object') {
Object.keys(obj).forEach(function(key) {
if (key === 'key8') {
result.push(obj[key]);
} else {
traverse(obj[key]);
}
});
}
}(obj));
return result;
}();
Logger.log(result) // >>> [value8, value8, value8, value8]
https://jsfiddle.net/ffuuur0L/
1st one is my answer. 2nd one is an answer by @Petr. My answer can use only when users know the structure of object. Petr's answer can use when users know the key. I think Petr's answer is useful. So I accepted Petr's answer.