-3

I'm trying to execute the following function using Fidler but still not getting the expected results. Basically, I have a deeply nested array that I would like to iterate through and get the sum. I have gone through the SO question but still can't see what I'm doing wrong.

The code is as follows:

EDIT

Thanks for the responses but the reason I was trying to use setTimeout() because the elements are many. See the full code below which I'm trying in Fiddler

const ElementsCount = 10000; //If I change this to 1000 its fine, when 10000 or more it gives error

const createDeeplyNestedArray = (ElementsCount) => {
      let retval = [1];
      for (let i = 0; i < ElementsCount - 1; i++) {
        retval = [1, retval];
      }
      return retval;
    };

const deeplyNestedArray = createDeeplyNestedArray(ElementsCount);
let sum = 0;

function sumArray(deeplyNestedArray) {
  let sum = 0;
  for (const entry of deeplyNestedArray) {
    if (typeof entry === 'number') {
      sum += entry;
    } else {
      sum += sumArray(entry);
    }
  }
  return sum;
}
var res = sumArray(deeplyNestedArray);
console.log(res); //Expected 10000 but getting maximum call stack exceeded
tmndungu
  • 167
  • 2
  • 8
  • Why do you need a setTimeout? – Terry Oct 11 '22 at 11:50
  • 4
    Does it have to be a recursive function? You could use `.flat(Infinity)` on the array, and then just iterate over that flattened array to sum the elements. – Andy Oct 11 '22 at 11:51
  • 2
    `return sum;` doesn't wait for the timeout, hence the result – Jaromanda X Oct 11 '22 at 11:52
  • deeplyNestedArray array can have 100,000 elements, I tried .flat(infinity) it giving maximum call stack exceeded – tmndungu Oct 11 '22 at 11:54
  • @Andy The only advantage of a recursive function is that it only iterates through the array once instead of multiple times like `Array.prototype.flat()` does, but I agree that in this case this is probably micro-optimisation and it's more readable to use `.flat(Infinity).reduce((acc, sum) => acc + sum, 0)` – Terry Oct 11 '22 at 11:54
  • Have you tried using the debugger to find the precise line? – Dexygen Oct 11 '22 at 11:54

2 Answers2

0

You don't need to use setTimeout at all. In fact, there is an easier way to perform the sum:

  1. Start sum with 0
  2. Iterate through a received array (from the first positional argument).
    • If the entry is a number, add it to the sum
    • If the entry is an array, recurse but adding the return function itself to the sum

In code it will look something like this:

function sumArray(arr) {
  let sum = 0;
  for (const entry of arr) {
    if (typeof entry === 'number') {
      sum += entry;
    } else {
      sum += sumArray(entry);
    }
  }
  return sum;
}

See proof-of-concept below, with optimisation using ternary operator:

const deeplyNestedArray = [1, [1, [1, [1, [1, [1, [1, [1, [1, [1]]]]]]]]]]

function sumArray(arr) {
  let sum = 0;
  for (const entry of arr) {
    sum += typeof entry === 'number' ? entry : sumArray(entry);
  }
  return sum;
}

const result = sumArray(deeplyNestedArray);
console.log("sum", result);
Terry
  • 63,248
  • 15
  • 96
  • 118
0

Basic answer: setTimeout is not waiting for calculation of sum, so after calling of sumArray - action is done inly one time. And after this - you are receiving answer where sum is 1.

const deeplyNestedArray = [1, [1, [1, [1, [1, [1, [1, [1, [1, [1]]]]]]]]]]
var sum = 0;

function sumArray() {
   let element = deeplyNestedArray.shift();

    if(element){
        if (Number.isInteger(+element)) sum += +element;
        else deeplyNestedArray.push(...element);

        sumArray();
    }
  return sum;
}

const result = sumArray();
console.log("sum",result);
xAqweRx
  • 1,236
  • 1
  • 10
  • 23