RangeError: call stack size error in JS function

  function findRandomDayIndex() {
    var dayindex = _.random(0, 39);
    var slot = dayslots[dayindex]; // array of 40 objects
    if(slot.filled === true || slot === undefined) {
      return findRandomDayIndex();
    } else {
      return dayindex;
    } 
  }

I get an error message:

RangeError: maximum call stack size exceeded iteration of the same function

What is the best way to write a function?

+4
source share
4 answers

You can try this version

function findRandomDayIndex()
{
   var dayindex = Math.random(0, 39);
   while( ( slot = dayslots[dayindex] ) == null )
       dayindex = Math.random(0, 39);
   return dayindex ;
}

Please check the consistency of the daily layer to prevent an infinite while loop anyway.

+4
source

You do not need recursion to do this. With a little refactoring, you can match your array to store indices, then filter undefined and fill in the values, and then get a random element from this new array, for example:

function findRandomDayIndex() {
    var notFilled = dayslots.map(function(value, index) {
        return {
            value: value,
            index: index
        };
    }).filter(function(day) {
        return day.value !== undefined && !day.value.filled;
    });
    if (!notFilled.length) {
        // all items of dayslots are undefined or filled
        // handle this case here
    }
    var dayindex = _.random(0, notFilled.length - 1);
    return notFilled[dayindex].index;
}
+1
source

Here, which is processed when all words are filled. The sample code returns -1, but you can update it to return something.

function findRandomDayIndex() {
    // Create an array of indexes for items that aren't filled
    var m = _.map(dayslots, function(v, k) {
        if (!v.filled) {
            return k;
        }
    });
    // The array will have undefined for those already filled, so we use lodash without to remove them
    m = _.without(m, undefined);
    if (m.length === 0) {
        // Handle when all slots are filled
        return -1;
    } else {
        // return a random index
        return m[_.random(0, m.length)];
    }
}

// Lets create some test data
var dayslots = [];
for (var i = 0; i < 40; i++) {
    dayslots.push({
        filled: false
    });
}

// Test our function    
console.log(findRandomDayIndex());

If you change the filled to true, you will get -1. A.

0
source

As @CodeiSir commented, since no slot was free code, it went into an endless loop. So I changed the code as shown below and it works fine. Thanks!

      if (_.findWhere(dayslots, {filled: false}) !== undefined) {
          var dayindex = _.random(0, 39); 
          var slot = dayslots[dayindex];
          console.log(dayslots.length);
          if(slot.filled === true || slot === undefined) {
            return findRandomDayIndex();
          } else {
            return dayindex;
          } 
        } 
0
source

Source: https://habr.com/ru/post/1621738/


All Articles