I try to run the number generator and it works correctly but sometimes it returns repeated numbers. I have tried some options but it keeps going the same way or it removes some number. What is the best alternative?
function sorteio() {
const numeroAleatorio = (min, max) => {
return Math.floor(Math.random() * 59 1)
};
const gerarNumerosEntre1a60 = n => {
const resultado = [];
for (let i = 0; i < n; i) {
resultado.push(numeroAleatorio(1, 60));
}
return resultado;
}
document.getElementById("resultado").innerHTML = gerarNumerosEntre1a60(6);
}
<button onclick="sorteio()">Sortear numeros!</button>
<h1 id="resultado"></h1>
CodePudding user response:
The numeroAleatorio
function selects a number from min
to max
randomly, but each selection is independent of the others. The function cannot 'remember' the past choices and select a number different from them.
To select multiple numbers from 1-60, you can push all numbers in one array, do a random shuffle, and select a contiguous subset.
here is another answer showing the Knuth shuffle algorithm: How to randomize (shuffle) a JavaScript array?
// random shuffle
function shuffle(array) {
let currentIndex = array.length, randomIndex;
while (currentIndex != 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
const gerarNumerosEntre1a60 = n => {
let array = [];
for(let i = 0; i < 60; i ) {
array.push(i);
}
return shuffle(array).slice(0, n)
}
CodePudding user response:
An alternative to Andy answer, using Set
Since adding an existing value to a Set does effectively nothing, this keeps adding values to the set until the size
reaches the required count
Warning: It's naive code that doesn't check that count greater than the possible values
function sorteio() {
const getRandom = (min, max, count) => {
const result = new Set;
while (result.size < count) {
result.add(Math.floor(Math.random() * (max - min 1)) min);
}
return [...result];
}
const gerarNumerosEntre1a60 = n => {
const resultado = getRandom(1, 60, n);
return resultado;
}
document.getElementById("resultado").innerHTML = gerarNumerosEntre1a60(6);
}
<button onclick="sorteio()">Sortear numeros!</button>
<h1 id="resultado"></h1>
CodePudding user response:
JaromandaX mentioned a good alternative in their comment, and here's another.
I've cached the elements up-front, and added a listener to the button (removing the inline JS from the HTML markup). Using a while
statement we can loop until six numbers have been added to the resultado
array. Within the loop we draw a number and if it's already in resultado
loop again, otherwise push the number.
Finally sort the array (because it's a lottery draw), and then join it, adding the string to text content of result
.
// Cache the elements, and add an event listener to
// the button
const result = document.querySelector('#resultado');
const button = document.querySelector('button');
button.addEventListener('click', () => sorteio(6));
// Use `min` and `max` within the function
function numeroAleatorio(min, max) {
return Math.floor(Math.random() * (max - min) min);
}
// Initialise `n` to 6 if it hasn't
// be supplied as an argument
function sorteio(n = 6) {
const resultado = [];
// Check the length of `resultado` - if it's
// less than the value of `n` get a new number.
// If the number is already in `resultado` loop again,
// otherwise push the number into the array
while (resultado.length < n) {
const number = numeroAleatorio(1, 60);
if (!resultado.includes(number)) {
resultado.push(number);
}
}
// Finally sort and join the array and add
// the string to the result text content
result.textContent = resultado
.sort((a, b) => a - b)
.join(', ');
}
<button>Sortear numeros!</button>
<h1 id="resultado"></h1>