Generatore di numeri casuali senza duplicati in Javascript?

Ho bisogno di aiuto per scrivere un codice che creerà un numero casuale da una matrice di 12 numeri e stamparlo 9 volte senza dupes. Questo è stato difficile da realizzare per me. Qualche idea?

var nums = [1,2,3,4,5,6,7,8,9,10,11,12]; var gen_nums = []; function in_array(array, el) { for(var i = 0 ; i < array.length; i++) if(array[i] == el) return true; return false; } function get_rand(array) { var rand = array[Math.floor(Math.random()*array.length)]; if(!in_array(gen_nums, rand)) { gen_nums.push(rand); return rand; } return get_rand(array); } for(var i = 0; i < 9; i++) { document.write(get_rand(nums)); } 

Il modo più efficace ed efficiente per farlo è mescolare i numeri e stampare i primi nove di essi. Usa un buon algoritmo shuffle. Cosa suggerito da Thilo ti darà risultati mediocri. Vedere qui.

Modifica Ecco un breve esempio dell’algoritmo di Knuth Shuffle:

 void shuffle(vector nums) { for (int i = nums.size()-1; i >= 0; i--) { // this line is really shorthand, but gets the point across, I hope. swap(nums[i],nums[rand()%i]); } } 

Prova una volta:

 //Here o is the array; var testArr = [6, 7, 12, 15, 17, 20, 21]; shuffle = function(o){ //v1.0 for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); return o; }; shuffle(testArr); 

Questo è relativamente semplice da fare, la teoria alla base sta creando un altro array che tiene traccia di quali elementi dell’array hai usato.

 var tempArray = new Array(12),i,r; for (i=0;i<9;i++) { r = Math.floor(Math.random()*12); // Get a random index if (tempArray[r] === undefined) // If the index hasn't been used yet { document.write(numberArray[r]); // Display it tempArray[r] = true; // Flag it as have been used } else // Otherwise { i--; // Try again } } 

Altri metodi includono mischiare l'array, rimuovere gli elementi usati dall'array o spostare gli elementi usati alla fine dell'array.

Se ti capisco correttamente, vuoi mescolare il tuo array.

Loop un paio di volte (la lunghezza dell’array dovrebbe fare), e in ogni iterazione, prendi due indici di array casuali e scambia i due elementi lì. (Aggiornamento: se sei veramente serio su questo, questo potrebbe non essere il miglior algoritmo ).

È quindi ansible stampare i primi nove elementi dell’array, che verranno ordinati in ordine casuale e non ripetuti.

Ecco un modo generico per ottenere numeri casuali tra min e max senza duplicati:

 function inArray(arr, el) { for(var i = 0 ; i < arr.length; i++) if(arr[i] == el) return true; return false; } function getRandomIntNoDuplicates(min, max, DuplicateArr) { var RandomInt = Math.floor(Math.random() * (max - min + 1)) + min; if (DuplicateArr.length > (max-min) ) return false; // break endless recursion if(!inArray(DuplicateArr, RandomInt)) { DuplicateArr.push(RandomInt); return RandomInt; } return getRandomIntNoDuplicates(min, max, DuplicateArr); //recurse } 

chiamare con:

 var duplicates =[]; for (var i = 1; i <= 6 ; i++) { console.log(getRandomIntNoDuplicates(1,10,duplicates)); }