admin管理员组文章数量:1123699
Given a json file with nested objects (not arrays) like:
{
"data": {
"UniqueName1": {
"name": "Bob",
"title": "the man"
},
"UniqueOtherName": {
"name": "Joe",
"title": "the myth"
},
"SuperUniqueName": {
"name": "Steve",
"title": "the legend"
}
}
}
Using Apps Script, how do I iterate through each unique sub-object to read the common properties therein?
function importLoLChampions() {
var files = DriveApp.getFilesByName("championFull.json");
if (files.hasNext()) {
var file = files.next();
var jsonString = file.getBlob().getDataAsString();
var jsonParsed = JSON.parse(jsonString);
//I can do this:
Logger.log(jsonParsed.data.UniqueName1.name);
Logger.log(jsonParsed.data.UniqueOtherName.name);
Logger.log(jsonParsed.data.SuperUniqueName.name);
//But I want to do this:
for(var champion in jsonParsed.data )
{
Logger.log(champion); //ok so far cause it's treating champion as a string
for(var championData in champion) //Doesn't work
{
//Champion is treated as a string value,
//i.e. seems to have lost object awareness
Logger.log(championData.name); //output: null
}
}
//Or this:
for(var i=0; i<jsonParsed.data.length); i++)
{
Logger.log(jsonParsed.data[i].name);
//Fails, treats jsonParsed.data[i] as a string
//and not an object
}
}
I've been struggling with this for a few hours, can't find a good answer. Is there a way to retrieve jsonParsed.data[i] as an object? Or another way to step through each sub-object to access the keys/values within?
Given a json file with nested objects (not arrays) like:
{
"data": {
"UniqueName1": {
"name": "Bob",
"title": "the man"
},
"UniqueOtherName": {
"name": "Joe",
"title": "the myth"
},
"SuperUniqueName": {
"name": "Steve",
"title": "the legend"
}
}
}
Using Apps Script, how do I iterate through each unique sub-object to read the common properties therein?
function importLoLChampions() {
var files = DriveApp.getFilesByName("championFull.json");
if (files.hasNext()) {
var file = files.next();
var jsonString = file.getBlob().getDataAsString();
var jsonParsed = JSON.parse(jsonString);
//I can do this:
Logger.log(jsonParsed.data.UniqueName1.name);
Logger.log(jsonParsed.data.UniqueOtherName.name);
Logger.log(jsonParsed.data.SuperUniqueName.name);
//But I want to do this:
for(var champion in jsonParsed.data )
{
Logger.log(champion); //ok so far cause it's treating champion as a string
for(var championData in champion) //Doesn't work
{
//Champion is treated as a string value,
//i.e. seems to have lost object awareness
Logger.log(championData.name); //output: null
}
}
//Or this:
for(var i=0; i<jsonParsed.data.length); i++)
{
Logger.log(jsonParsed.data[i].name);
//Fails, treats jsonParsed.data[i] as a string
//and not an object
}
}
I've been struggling with this for a few hours, can't find a good answer. Is there a way to retrieve jsonParsed.data[i] as an object? Or another way to step through each sub-object to access the keys/values within?
Share Improve this question edited 18 hours ago Wicket 38k9 gold badges77 silver badges189 bronze badges asked yesterday user645379user645379 255 bronze badges4 Answers
Reset to default 1You can use a for...of
statement with Object.entries()
to iterate over the collection of objects. And you can also leverage destructuring assignment to make the things a little more readable.
Given:
var json = {
"data": {
"UniqueName1": {
"name": "Bob",
"title": "the man"
},
"UniqueOtherName": {
"name": "Joe",
"title": "the myth"
},
"SuperUniqueName": {
"name": "Steve",
"title": "the legend"
}
}
}
Then you can do this:
function iterateOverEntries(json) {
for (const [uniqueName, { name, title }] of Object.entries(json.data)) {
console.log(JSON.stringify({
uniqueName,
name,
title
}, undefined, 4));
}
}
Note: Google Apps Script now supports modern Javascript, so try to use let
and/or const
instead of var
, console.log
instead of Logger.log
, etc.
To traverse nested JSON objects with distinct names in Google Apps Script, recursion can be employed effectively. Below is a detailed guide:
Sample JSON
{
"person": {
"name": "John",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"postalCode": "12345"
},
"contacts": {
"email": "[email protected]",
"phone": "555-1234"
}
}
}
Code for Iterating Through Nested JSON The following code demonstrates this process:
function traverseNestedJSON(jsonObject) {
for (var key in jsonObject) {
if (jsonObject.hasOwnProperty(key)) {
if (typeof jsonObject[key] === 'object' && jsonObject[key] !== null) {
// Recursively invoke the function for nested objects
console.log("Entering nested object: " + key);
traverseNestedJSON(jsonObject[key]);
} else {
// Output the key and value for non-object properties
console.log(key + ": " + jsonObject[key]);
}
}
}
}
function executeExample() {
var json = {
"person": {
"name": "John",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"postalCode": "12345"
},
"contacts": {
"email": "[email protected]",
"phone": "555-1234"
}
}
};
traverseNestedJSON(json);
}
Explanation:
- Iterate through keys: Utilize a
for...in
loop to go through the keys of the JSON object. - Verify property ownership: Employ
hasOwnProperty
to confirm that you are not accessing properties from the prototype chain. - Identify nested objects: If the value associated with a key is an object, recursively call the function.
- Process non-object values: Directly log or handle the key-value pairs.
Output:
Entering nested object: person
name: John
age: 30
Entering nested object: address
street: 123 Main St
city: Anytown
postalCode: 12345
Entering nested object: contacts
email: [email protected]
One of the earlier answers noted:
Google Apps Script now supports modern Javascript, so try to use
let
and/orconst
instead ofvar
,console.log
instead ofLogger.log
, etc.
If that's the case, then a function I use often, might make this simpler.
const pathEntries = (o, path = []) => [
... (path.length > 0 ? [[path, o]] : []),
... (Object (o) === o ? Object.entries(o).flatMap (
([k, v]) => pathEntries(v, [...path, Array.isArray(o) ? Number(k) : k])
) : [])
]
Applied to your object it would yield:
[
[ ["data"], __original object here__ ],
[ ["data", "UniqueName1"], {name: "Bob", title: "the man"} ],
[ ["data", "UniqueName1", "name"], "Bob" ],
[ ["data", "UniqueName1", "title"], "the man" ],
[ ["data", "UniqueOtherName"], {name: "Joe", title: "the myth"} ],
[ ["data", "UniqueOtherName", "name"], "Joe" ],
[ ["data", "UniqueOtherName", "title"], "the myth" ],
[ ["data", "SuperUniqueName"], {name: "Steve", title: "the legend"} ]
[ ["data", "SuperUniqueName", "name"], "Steve" ],
[ ["data", "SuperUniqueName", "title"], "the legend" ]
]
And then you could use the resulting array of path/value pairs to log output or to build something else.
const pathEntries = (o, path = []) => [
... (path.length > 0 ? [[path, o]] : []),
... (Object (o) === o ? Object.entries(o).flatMap (
([k, v]) => pathEntries(v, [...path, Array.isArray(o) ? Number(k) : k])
) : [])
]
const data = {data: {UniqueName1: {name: "Bob", title: "the man"}, UniqueOtherName: {name: "Joe", title: "the myth"}, SuperUniqueName: {name: "Steve", title: "the legend"}}}
console.log(pathEntries(data))
.as-console-wrapper {max-height: 100% !important; top: 0}
Thank you everyone, all were relevant and helpful! The AddOnDepot's response is spot on. For my incredibly unsavvy code, I ended up using something like:
for (const [dataKey, peopleValues] of Object.entries(jsonParsed.data)) {
Logger.log(`${dataKey}`);
Logger.log(peopleValues.name);
Logger.log(peopleValues.title);
/* And was able to apply the same concept to access deeper nested values!
for( const [deeperNestedKeys, deeperData] of Object.entries(peopleValues))
{
Logger.log(deeperData.otherValue);
}
*/
}
My first tip off was actually from an old stackoverflow post that I didn't fully understand at first, so credit also to: https://stackoverflow.com/a/62735012/645379
本文标签: javascriptHow to iterate through nested json objects with unique names in Apps ScriptStack Overflow
版权声明:本文标题:javascript - How to iterate through nested json objects with unique names in Apps Script - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736589431a1945054.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论