How to check the depth of an object?

I’m working on a permissions system with variable depth; depending on the complexity of a page, there could be more or less levels. I searched StackOverflow to find if this has been asked before, couldn’t find it.

If I have this object:

{foo:{bar:{baz : 'baa'}}}

I need it to return 3, it has 3 levels to it.

With this object:

{abc: 'xyz'} 

It would have to be 1.

This is what I have so far:

utils.depthOf = function(object, level){
    // Returns an int of the deepest level of an object
    level = level || 1;

    var key;
    for(key in object){
        if (!object.hasOwnProperty(key)) continue;

        if(typeof object[key] == 'object'){
            level++;
            level = utils.depthOf(object[key], level);
        }
    }

    return level;
}

The problem is it counts sister elements too. It’s actually not getting depth, it’s counting all members of an object.

Well, here you go buddy, a function that does exactly what you need!

utils.depthOf = function(object) {
    var level = 1;
    for(var key in object) {
        if (!object.hasOwnProperty(key)) continue;

        if(typeof object[key] == 'object'){
            var depth = utils.depthOf(object[key]) + 1;
            level = Math.max(depth, level);
        }
    }
    return level;
}

A lot easier than we thought it would be. The issue was how it was incremented, it shouldn’t have been recursively adding, rather getting the bottom-most and adding one, then choosing the max between two siblings.

This old question was recently resurrected and I don’t see any answers as simple as this one (to be fair, this uses techniques not available when the question was written):

const objectDepth = (o) =>
  Object (o) === o ? 1 + Math .max (-1, ... Object .values(o) .map (objectDepth)) : 0

console .log (objectDepth ({foo: {bar: {baz: 'baa'}}}))
console .log (objectDepth ({abc: 'xyz'}))

This, like most answers here, will fail when the input object is cyclic. An answer that addresses that limitation would require much more sophistication.

Read More:   Using CSS and HTML5 to create navigation buttons using trapezoids

Back from the dead! Throwing my solution into the mix –

function depth (t, mem = new Set)
{ if (mem.has(t))
    return Infinity
  else switch (mem.add(t), t?.constructor)
  { case Object:
    case Array:
      return 1 + Math.max
       ( -1
       , ...Object
           .values(t)
           .map(_ => depth(_, mem))
       )
    default:
      return 0
  }
}

console.log(depth({a: {b: {c: "z"}}}))   // 3
console.log(depth({a: "z"}))             // 1
console.log(depth({}))                   // 0
console.log(depth("z"))                  // 0
console.log(depth({a: [{b: "z"}]}))      // 3

const a = []
a[0] = a
console.log(depth(a))                    // Infinity

We can use the reg:

function getHowManyLevel(obj) {
  let res = JSON.stringify(obj).replace(/[^{|^}]/g, '')
  while (/}{/g.test(res)) {
    res = res.replace(/}{/g, '')
  }
  return res.replace(/}/g, '').length
}

This should do it, if you wanna keep it short:

function maxDepth(object) {
    if (typeof object !== "object" || object === null) {
        return 0;
    }

    let values = Object.values(object);

    return (values.length && Math.max(...values.map(value => maxDepth(value)))) + 1;
}

I used a dirty but efficient way :

The good point is that there is no Regex in it, because regex is costly in process time

getObjectDepth = (object) => {
      // json to array of parenthesis array: ['{','{','}','}',]
      let string = JSON.stringify(object)
          .split('')
          .filter(char => ['{', '}'].includes(char) );

      let currentDepth = 0;
      let maxDepth = 0;
      string.forEach(char => {
          if (char === '{') currentDepth++;
          if (char === '}') currentDepth--;
          if (currentDepth > maxDepth) maxDepth = currentDepth;
      });

      return maxDepth
}

It will only work if the object has no parenthesis in a string value though.


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Similar Posts