0

As part of developing custom functions for a google sheet using Google Apps Script (GAS), I am trying to get a flattened tree of an object's property (key?) names. I'm not interested in any of the values, I just want to print out a dot notation tree of all of the object's property (key) names. The object has an unknown depth and unknown structure.

example:

{
    "level1_prop1": "stuff",
    "level1_prop2": 0,
    "level1_prop3": 50,
    "level1_prop4": [{
            "level2_prop1": "more stuffs, and things",
            "level2_prop2": "10000",
            "level2_prop3": {
                "level3_prop1": {
                    "level4_prop1": "other stuff",
                    "level4_prop1": "so much stuff",
                },
                "level3_prop2": null,
            }
        }, {
            "level2_prop1": "still more and more",
            "level2_prop2": "10001",
            "level2_prop3": {
                "level3_prop1": {
                    "level4_prop1": "other stuffssssss",
                    "level4_prop1": "so much stuffssssssss",
                },
                "level3_prop2": null,
            }
        }         
    ]
}

desired output in a string or array of strings:

object.level1_prop1
object.level1_prop2
object.level1_prop3
object.level1_prop4
object.level1_prop4.level2_prop1
object.level1_prop4.level2_prop2
object.level1_prop4.level2_prop3
object.level1_prop4.level2_prop3.level3_prop1
object.level1_prop4.level2_prop3.level3_prop1.level4_prop1
object.level1_prop4.level2_prop3.level3_prop1.level4_prop2
object.level1_prop4.level2_prop3.level3_prop2

I ultimately want to use this to selectively remove specific properties/keys throughout the entire object. for example:

remove(object.level1_prop4.level2_prop3.level3_prop1) 

would result in

object.level1_prop1
object.level1_prop2
object.level1_prop3
object.level1_prop4
object.level1_prop4.level2_prop1
object.level1_prop4.level2_prop2
object.level1_prop4.level2_prop3
object.level1_prop4.level2_prop3.level3_prop2

update: adding specification that the answer is intended for use in a custom Google Apps Script (GAS) function, since the first wave of answers are causing errors when I paste them into my code.gs file. My apologies to those who already answered under a different pretense.

swv
  • 691
  • 1
  • 12
  • 28
  • How is this object being retrieved? – TheAddonDepot Apr 01 '19 at 22:41
  • 2
    Possible duplicate of [Fastest way to flatten / un-flatten nested JSON objects](https://stackoverflow.com/questions/19098797/fastest-way-to-flatten-un-flatten-nested-json-objects) – David Alvarez Apr 01 '19 at 22:54
  • @DavidAlvarez - yes, the accepted answer (https://stackoverflow.com/a/19101235/2051870) on that question solved mine as well. Thank you for the quick answer! – swv Apr 02 '19 at 15:54

3 Answers3

1

This will return an array with all of the indexes of object. It also will include nested array of objects

function objectDeepKeys(obj){
  return Object.keys(obj)
    .filter(key => obj[key] instanceof Object)
    .map(key => objectDeepKeys(obj[key]).map(k => `${key}.${k}`))
    .reduce((x, y) => x.concat(y), Object.keys(obj))
}

Took it from https://stackoverflow.com/a/47514598/11294419

Tadeo Hndz
  • 46
  • 6
0
function doit(arr, obj, start){
    if (Array.isArray(obj)) {
        asdf.map((i, idx) => doit(arr, i, start + `${idx}.`))
    } else if (typeof obj == 'object') {
        Object.keys(obj).map(k => {
            arr.push(start + `${k}`)
            doit(arr, obj[k], start + `${k}.`)
        })
    }
}

Then just a = []; obj = [your object]; doit(a, obj, ''); console.log(a)

ryan28561
  • 302
  • 2
  • 11
0

Here is something like what your after.

Your example data also has arrays, so I would have expected an output like -> object.level1_prop4[0].level2_prop1 etc, so I've included that one too if you uncomment the relevant line.

const v =
{
    "level1_prop1": "stuff",
    "level1_prop2": 0,
    "level1_prop3": 50,
    "level1_prop4": [{
            "level2_prop1": "more stuffs, and things",
            "level2_prop2": "10000",
            "level2_prop3": {
                "level3_prop1": {
                    "level4_prop1": "other stuff",
                    "level4_prop1": "so much stuff",
                },
                "level3_prop2": null,
            }
        }, {
            "level2_prop1": "still more and more",
            "level2_prop2": "10001",
            "level2_prop3": {
                "level3_prop1": {
                    "level4_prop1": "other stuffssssss",
                    "level4_prop2": "so much stuffssssssss",
                },
                "level3_prop2": null,
            }
        }         
    ]
};

function dotList(o) {
  const s = new Set();
  function dotIt(o, p = '') {
    Object.entries(o).forEach(([k, v]) => {
      if (typeof v === 'object' && v) {
        if (Array.isArray(v)) {
          v.forEach((v) => dotIt(v, `${p}${k}.`));  //if you also wanted the array [ix] bit too
          //uncomment line below for array indexes key[v].key          
          //v.forEach((v, ix) => dotIt(v, `${p}${k}[${ix}].`));
        } else dotIt(v, p + k +  ".");
      }
      s.add(p + k);
    });
  }
  dotIt(o, 'object.');
  return Array.from(s);
}

dotList(v).forEach(e => console.log(e));
Keith
  • 22,005
  • 2
  • 27
  • 44