Reputation: 3
I need to generate a random value, except for other defined ones, it works, but sometimes the "selectedTroop ()" method returns an undefined value ...
var troopIDs = [1, 2, 3, 4];
const exceptedTroops = [1, 2, 3];
function rand(min, max) {
return Math.floor((Math.random() * max) + min);
}
function selectedTroop() {
var troop = troopIDs[rand(1, troopIDs.length)];
for(a = 0; a < exceptedTroops.length; a++) {
if(troop == exceptedTroops[a]) {
troop = troopIDs[rand(1, troopIDs.length)];
a = 0;
}
}
return troop;
}
console.log(selectedTroop());
Upvotes: 0
Views: 441
Reputation: 817030
Why does it return undefined values?
It'd return undefined
if rand(1, troopIDs.length)
produces an array index outside of the range of troopIDs
. Array indexes are 0-based:
var troopIDs = [1, 2, 3, 4];
// array index 0 1 2 3
I.e. the highest index in an array of length 4
is 3
.
Lets look at what rand
returns:
Math.random()
returns a value in the range of [0,1)
(this is interval notation, [
and ]
mean that the value is included the internval, (
and )
mean that that value is excluded. In other words 0 <= x < 1
)Math.random() * 4
(troopIDs.length
) might therefore be a value in the range of [0,4)
.... + 1
(min
) changes that range to [1,5)
Math.floor(...)
changes the range to [1,4]
(note that the upper boundary is included, as opposed to previous steps, i.e. 1 <= x <= 4
).So the way you call rand
can produce the value 4
, but the highest index is in the array is 3
, so troopIDs[4]
returns undefined
.
Either the implementation of rand
is incorrect or you are passing the wrong arguments.
If you want rand
to return a random value that includes the max boundary, then keep the implementation but call it with
rand(1, troopIDs.length - 1)
instead.
If you want to exclude the max boundary, then you to change the implementation to
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}
Also note that passing 1
as first argument will mean that you will never get 0
back from rand
.
Upvotes: 3
Reputation: 302
The fundamental rule for an array is that you start counting the indexes at 0. This means that in troopIDs
, The first element is at index 0, the second at index 1, the third at index 2, and the fourth at index 3.
This means that your random number cannot be greater than three, since you have only defined elements up to the third index. You're getting an undefined
because you check for random numbers from 1-4, not 0-3. This solves the problem:
var troop = troopIDs[rand(0, troopIDs.length - 1)];
We get the element in the array based on a random number from 0, the start of the array, to the length minus 1. Well, why minus 1 you might ask? This is because the length property returns how many elements are in the array. In the current case of troopIDs
, there are 4 total elements. Remember though, you can only check up to the third index because we start counting array elements from 0. This means we can take the length of the array minus 1 to get the last element in the array.
Hope this helped!
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
Upvotes: 2