1

I'm using regular JavaScript.

As the headline suggests I'm getting a RangeError and I don't really know how to avoid it. The real problem is that I should not get it, and indeed if I refresh the page there's a one out of ten chance (estimated) that the error isn't thrown.

THE CODE: (its about picking random objects from an array)

I have a an array like this:

var array = ["item1", "item2", "item3", "item4"]

and so on, actually I have like 5 arrays, containing together around 4000 characters. I use a function to generate a random number:

 function getRandomNumber(start, range) {
     range = range + 1;
     return Math.floor( (Math.random() * (range - start) ) + start );
}

This function works and I even refined my initial approach with help from the web to look like as it is now.

So I call this function like this:

function getObjects() {
    var randomObject1 = array[getRandomNumber(1, array.length -1)]
    var randomObject2 = array[getRandomNumber(1, array.length -1)]
    var randomObject3 = array[getRandomNumber(1, array.length -1)]

    var drawnItems = [randomObject1, randomObject2, randomObject3]

    if(drawnItems.length != new Set(drawnItems).size) {
        getObjects()
    }
}

I need multiple objects drawn each round, so I do this multiple times as shown. I do end up with an array that contains the random items drawn like above.

Then I use this code to determine if the drawn items can be stored in a Set, which is not important, but a convenient way of checking if there are any objects that were drawn twice. => I can only have each object once in the final output.

I can see how this all can be problematic, but I don't really understand why the computer faces the problem but I don't, if I refresh like a few times. What I'm saying is that in fact the computer will try more often than I have to refresh to hit a valid constellation. Why does the PC face the problem even though he's trying even more often?

This first happened when I tried drawing 3 objects out of an array containing only 4. If I draw from my large 100+ objects array I never face problems.

TravisScript
  • 30
  • 1
  • 7

2 Answers2

1

There's an infinite loop in getObjects function

this part:

//...
 if(drawnItems.length != new Set(drawnItems).size) {
      getObjects()
   }
//...

This function calls itself infinite times until it reaches the limit. That's why you're getting this error. Try loops instead maybe it'll help.

Also I found something helpful for you: Maximum call stack size exceeded error

Arda Ravel
  • 68
  • 2
  • 7
  • It’s infinite until the items match the criteria of a Set. So it’s only infinite if I draw more objects than there are unique ones in the array. Is that correct? At least is worked for months now. I’ll look into your solution though for sure! – TravisScript Jun 19 '21 at 19:13
  • Well **if it works with the unique ones** then you need to define a function (or use array filter function) to remove the duplicates but by doing that you're moving away from the best practices I guess. – Arda Ravel Jun 19 '21 at 19:20
1

This is a recursion issue. Your function is calling itself over and over again untill stack gets filled and causes the error shown.

If you remove these lines of code you will solve the error:

if(drawnItems.length != new Set(drawnItems).size) {
    getObjects()
}

Is there any reason why you had that if condition to perform recursion?

Edit:

In order to avoid duplicated values you can use the following code to also remove the recursion:

//First object won't be duplicated, so we declare it directly
var randomObject1 = array[getRandomNumber(1, array.length -1)];

var randomObject2 = null, randomObject3 = null;

do {
    randomObject2 = array[getRandomNumber(1, array.length -1)];
} while (randomObject2 == randomObject1);

do {
    randomObject3 = array[getRandomNumber(1, array.length -1)];
} while (randomObject3 == randomObject1 || randomObject3 == randomObject2);

With the code above you'll keep generating random values for randomObject2 and randomObject3 while they have the same value as another.

Jorge C.M
  • 375
  • 3
  • 11
  • this is to ensure I do not draw the same object twice, which is possible the way I set it up. – TravisScript Jun 19 '21 at 19:30
  • I've updated my answer so you can remove recursion while ensuring no duplicates are found at your results. – Jorge C.M Jun 19 '21 at 23:55
  • Good approach, in the end I went with just shuffling the arrays each and then just using items from them one after another. The arrays are constant and contain no duplicates, also I had to draw around 20 objects. – TravisScript Jan 24 '22 at 11:07