7

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?

1
  • this is not the best way to do it but following your idea you could use JSON.stringify to convert the array before and after .flat instead of comparing length Commented Mar 29, 2019 at 15:05

12 Answers 12

24

I think a recursive approach is simpler. If your current item is an Array determine the max depth of its children and add 1.

function getArrayDepth(value) {
  return Array.isArray(value) ? 
    1 + Math.max(0, ...value.map(getArrayDepth)) :
    0;
}



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);

Edit Shoutout to Daniele Fioroni for catching an edge-case my code didn't handle: empty arrays. I've updated my code. But still, leave some upvotes over there as well.

Sign up to request clarification or add additional context in comments.

2 Comments

why do you log testRy ? And why do you log it twice?
@JeremyThille, I copied that part right from the question. I've only changed the implementation of getArrayDepth
10

@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

Comments

5

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]]))

3 Comments

You don't need to pass depth when you call the function. You should also show the actual result in the snippet.
no need for t => getArrayDepth(t) - just use .map(getArrayDepth)
I'd change it so the guard is at the top eg. if (!Array.isArray(obj)) return 0; Then leave out the else statement and simply return 1 + Math.max(...obj.map(getArrayDepth));
4

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([]));

Comments

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]

Comments

2

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'

Comments

1

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.

Comments

0

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;
}

Comments

0

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));

Comments

0
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)

Comments

0
function arrayDepth(arr) {
  return Array.isArray(arr) ? Math.max(0, ...arr.map(arrayDepth))+1:0;
}



console.log(arrayDepth(null)); // expect 0
console.log(arrayDepth([])); // expect 1
console.log(arrayDepth([3.14])); // expect 1
console.log(arrayDepth([1, 2, [3], 4])); // expect 2
console.log(arrayDepth([1, 2, [3], [4, [5]]])); // expect 3

Comments

0

Here's a code that gives you depth along with a flatten array. I was asked to flat the array without using flat() method. Here's the code-

function depthAndFlat(){
    const flatArr = [];
    function getArrDepth(arr){
        let maxDepth = 1;

        for(let item of arr){

            if(Array.isArray(item)){
                let depth = 1 + parseInt(getArrDepth(item));
                maxDepth = Math.max(maxDepth, depth);
            }else{
                flatArr.push(item);
            }
        }

        return [maxDepth, flatArr];
    }
    return getArrDepth;
}
const innerFun = depthAndFlat();
const res3 = innerFun(arr);
console.log("Depth :", res3[0], "Flat Array: ", res3[1])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.