The script:
let col1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
let col2 = [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
for(let i = 0; i < 5; i++) {
const random = Math.floor(Math.random() * col1.length + 1)
const index = col1.indexOf(random)
const number = col1.at(index)
col1.splice(index, 1)
console.log(number)
}
for(let i = 0; i < 5; i++) {
const random = Math.floor(Math.random() * col2.length + 1)
const index = col2.indexOf(random)
const number = col2.at(index)
col2.splice(index, 1)
console.log(number)
}
The first for loop always generates 5 random numbers from the first array. But the second for loop always shows the same results (30, 29, 28, 27, 26). What’s causing this behavior?
3
Answers
You are trying to get the index of the value in col2. You have an array of 15 items. Your index will always be less than the 16 (the lowest number in your second set), and by extension,
col2.indexOf(random)
will always return -1, because your random value less than 16 is not in that array, and indexOf returns -1 if it cannot find the index of your supplied value. Splicing with -1 will return the last value in your array, hence why you get 30-26. See the MDN docs for indexOf:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
generates a random integer between 0 and 15, since
col2.length
is15
. Then,always returns
-1
, since there isn’t any element with valuerandom
incol2
. So thenassigns always
col2
‘s last item tonumber
, which changes each iteration sinceremoves
col2
‘s last element.If you want five different elements from each array, you can just do:
EDIT: removed the
+1
inMath.floor()
to stay within range.Your second for loop effectively ends up calling
at()
with-1
five times:When you pass
-1
to.at()
it gives you the last element in your array, and and since the following.splice(-1, 1)
call removes the last element fromcol2
, the next iteration will give you the next last element and so on.The main issue with your code is that you’re treating
random
as an element within your array, when really it’s an index (if you remove the+1
). This ends up with your.indexOf()
code not being able to find therandom
element in your array, and thus settingindex
to-1
. The only reason it happens to work in your first example is because your elements are consecutive starting from1
, sorandom
in that case just so happens to match up with an element from your array. But in the more general case (likecol2
), that won’t be the case.Instead, you can get your random index, access the element at that index using bracket notation (no need for
.indexOf()
or.at()
), and then remove the element from your source array (to avoid doubling-up on the same element):Or, an alternative approach would be to shuffle your array, and then use
.slice()
to get the firstn
elements: