1

I've been trying to figure out how to count the number of nested arrays recursively in javascript but I can't seem to wrap my head around how you would do that. Like I know we'll need to use a count variable in there and we'll need to be able to access the elements but how can we count each time a new array is seen inside? Here's the problem: Given a nested array where each element may be 1) an integer or 2) an array, whose elements themselves may be integers or further arrays, count the total number of arrays.

I've tried this and I have no clue what I'm doing when it comes to deciding whether we've seen a new array.

`

function countArrays(array) {
  //counting the first array
    let sumTotal = 1;

    for(let element in array);
        if(Array.isArray(array))
            sumTotal += countArrays(array)
};

console.log(countArrays([1, 2, 3])) // 1
console.log(countArrays([1, [1, 2, 3], 3])) // 2

`

3 Answers 3

3

You need to iterate the items, not keys of the array/object.

    for (let element of array)
                     ^^       ^

Omit semicolon, because this prevents the next statement to be a part of the loop. it is just the next statement after the loop.

Then check if the element is an array.

        if (Array.isArray(element))

and the result of the recursive call with this item.

Finally return the count.

    return sumTotal;

If no return statement is found, the function returns allways undefined.

function countArrays(array) {
    let sumTotal = 1;

    for (let element of array)
        if (Array.isArray(element))
            sumTotal += countArrays(element);

    return sumTotal;
}

console.log(countArrays([1, 2, 3])) // 1
console.log(countArrays([1, [1, 2, 3], 3])) // 2

Maybe it is easier to wrap all statments of loops and conditions with a block statement to get a visual feedback of the scope of application.

function countArrays(array) {
    let sumTotal = 1;

    for (let element of array) {
        if (Array.isArray(element)) {
            sumTotal += countArrays(element);
        }
    }

    return sumTotal;
}

console.log(countArrays([1, 2, 3])) // 1
console.log(countArrays([1, [1, 2, 3], 3])) // 2

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

5 Comments

Thank you Nina! That makes more sense now..I'm just starting to learn recursion and I'm having trouble grasping the whole idea. Thanks again!!
Can you explain to me what the recursive line is doing? How to dissect the sumTotal += countArrays(element)
this line takes the result of calling function countArray with an element of the array which is an array and assigns the result to the actual value of sumTotal.
Okay, so is that also what makes the code keep running to iterate to the next element and so forth?
yes. it calls the function with a different paramter and untill all nested calls are not finished, the calling function waits for the result.
1

Nina's answer is great. It explains what you did wrong and how to fix it.

But if you're looking for a simpler recursive version, you might try something like this:

const countArrays = (xs) =>
  Array .isArray (xs)
    ? 1 + xs .map (countArrays) .reduce ((a, b) => a + b, 0)
    : 0

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

But I would prefer to extract the helper function sum, and write it like this:

const sum = ([x, ...xs]) =>
  x == undefined ? 0 : x + sum (xs)

const countArrays = (xs) =>
  Array .isArray (xs)
    ? 1 + sum (xs .map (countArrays))
    : 0

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

(Usually I would write sum using the more efficient reduce, but since you're studying recursion, it's probably useful to see a recursive version of that too.)

Comments

0

Another way you can do this is by just using a plain old for loop if you're confused on when to use a of or in loop. We can do this by getting the length of the array and looping through and looking for if that index in the array is indeed an array.

function countArray(arr) {
    let count = 1;
    for (let i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
           count++;
        }
    }
    return count;
} 

2 Comments

Ah yes, thank you benji! I do need to use a recursive solution to this problem, though, which I don't really understand what it's doing when calling it added to the count variable.
countArray ([1, [2], 3, [4, 5, [6, 7], 8, [9, 10, [[[11]]]]]]) //=> 3/ It presumably should be 8.

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.