'Get array's depth in JavaScript

In order to get the array's depth I thought I can use the flat() method like so:

function getArrayDepth(ry){
  // number of levels: how deep is the array
  let levels = 1;
  // previous length
  let prev_length = 1;
  // current length
  let curr_length = ry.length;
  //if the resulting array is longer than the previous one  add a new level
  while(curr_length > prev_length){
  ry = ry.flat();
  prev_length = curr_length
  curr_length = ry.length;
  levels ++
  }
  return levels;
}



let testRy = [1,2,[3,4,[5,6],7,[8,[9,91]],10],11,12]

console.log(testRy);

console.log(getArrayDepth(testRy))

console.log(testRy);

It seams it works BUT if one of the arrays inside has a length of 1

let testRy = [1, 2, [3, 4, [5, 6], 7, [8, [9] ], 10], 11, 12]

the function fails since the flattened array is as long as the previous one.

Is there a better way to get the depth of an array in javascript?



Solution 1:[1]

You can use a recursive function:

function getArrayDepth(obj) {
    if (Array.isArray(obj)) return 1 + Math.max(...obj.map(t => getArrayDepth(t)))
    else return 0
}


console.log(getArrayDepth([1,2,[3,4,[5,6],7,[8,[9,91]],10],11,12]))
console.log(getArrayDepth([1,[1]]))

Solution 2:[2]

function test(arr) {
  return 1 + (arr instanceof Array ? arr.reduce(function(max, item) {
    return Math.max(max, test(item));
  }, 0) : -1);
}



let testRy = [1,2,[3,4,[5,6],7,[8,[9,91]],10],11,12];

console.log(test(testRy));
console.log(test([]));

Solution 3:[3]

@thomas solution is neat, but I found an edge case with empty array

getArrayDepth([]) would return -Infinity, which was not what I expected, so I slightly retouched it as follows

const getArrayDepth = value => Array.isArray(value) ?
    1 + Math.max(0, ...value.map(getArrayDepth)) :
    0;

getArrayDepth([]); // 1
getArrayDepth([[]]); // 2
getArrayDepth([[[]]]); // 3

Solution 4:[4]

I think you could use Infinity to flatten your array. MDN gives an example. Not sure how efficient this is though.

const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];

arr4.flat(Infinity);

// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Solution 5:[5]

This is my first time on here so please bear with me. My approach checks the data type of the given function argument. If it's an Array, it must be at least 1 level deep, so add 1 to depth. Flatten the array, then repeat the process via recursion.

'use strict'

let arr = [1,2,[3,[4,[5,[10,45,[7,8]]],6],7],8]
let depth = 0

function getArrayDepth(array){
    if(Array.isArray(array)){
        ++depth
        for(let i=0;i<array.length;i++){
            if(Array.isArray(array[i])) {
                arr = arr.flat()
                getArrayDepth(arr)  
            }
        }
        return `Array depth = ${depth}`
    }
    return console.error(`Invalid input: argument data type must be 'array'`)
}

console.log(getArrayDepth(arr))//Array depth = 6
console.log(getArrayDepth({})) //Invalid input: argument data type must be 'array'

Solution 6:[6]

Convert the array to string lets assume We are given a string having parenthesis like below “( ((X)) (((Y))) )” We need to find the maximum depth of string, like 4 in above example. Since ‘Y’ is surrounded by 4 balanced parenthesis.

Take two variables max and current_max, initialize both of them as 0. Traverse the string, do following for every character a) If current character is ‘(’, increment current_max and update max value if required. b) If character is ‘)’ means we previously had a ‘(’ character so decrement current_max without worry but dont reduce max value .

If current_max is greater than max then update max value to current_max at that instance. after traverse is completed the max is is the depth of the array.

Solution 7:[7]

This one is a bit easier to understand, if you'd like.

var array = [
[0, 1],
[1, 2, 3, [1, 0]],
[2, 3, [1, 2, [5]]],
[1, [6, 3, [1, 2, [1, 0]]]],
[2]
]

function depth(array, rec) {
if (!Array.isArray(array)) throw new Exception('not an array');

var res = rec;
for(var i = 0; i < array.length; ++i) {
    if (Array.isArray(array[i])) {
    var subDepth = depth(array[i], rec + 1);
    if (subDepth > res) {
        res = subDepth;
    }
  }
}
return res;
}

Solution 8:[8]

You can use a recursive function that adds a counter when an array hits and you could also use map if you want to deal with Objects (Ofcourse you can use for loop though). dont forget to initialize the counter to 1 since the first iteration is not counted on initial loop.

Although @thomas answer is perfect when you look into the perfomance, you can select with respect to your need.

Here is the Js Bench Mark result. enter image description here

const sampleArray = [1, 2, [3, 4, [5, 6], 7, [8, [9, 91]], 10], 11, 12, []];
let count = 1;
const getDepth = (array) => {
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    if (Array.isArray(element)) {
      count += 1;
      getDepth(element);
    }
  }
  return count;
};

console.info("depth", getDepth(sampleArray));

Solution 9:[9]

const depth = (arr) => arr.reduce((count,v) => !Array.isArray(v) ? count : 1 + depth(v),1);

console.log(depth([])); // 1
console.log(depth([1,[2,[3]]])); // 3
console.log(depth([1,2,[3,4,[5,6],7,[8,[9,91]],10],11,12])); // 4
console.log(depth([[[[[]]]]])); // 5
console.log(depth([1,[2,[3,[4,[5,[6,[7,[]]]]]]]])); // 8 
console.log(depth([1,[2,[3,[4,[5,[6,[7,[8,[[[]]]]]]]]]]])); // 11

first, we'll loop over "arr" with "reduce" and assign "1" as the default value for "count"

arr.reduce((count,v) => ... ,1)

on each iteration, if the current value "v" is not an array then return "count"

!Array.isArray(v) ? count

else, if "v" is an array then add "1" to each recursive invocation of "depth" with "v" as its argument

: 1 + depth(v)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 nick zoum
Solution 3 Daniele Fioroni
Solution 4 Andrei Egorov
Solution 5 enxaneta
Solution 6 Uday Kiran
Solution 7 Patrick Leonard
Solution 8
Solution 9