2011-08-20 10 views
7

Por lo tanto, estoy intentando seleccionar una entrada aleatoria de una matriz, y luego hacerlo de modo que esa entrada en particular no se seleccione de nuevo hasta que se haya seleccionado cada entrada. Básicamente, no quiero ver ninguna de las mismas entradas, hasta que se hayan seleccionado todas las entradas en la matriz.Selección de matriz aleatoria sin seleccionar dos veces en JavaScript

Así que si este fuera mi gama ...

keywords = 
[ 
"ppc", 
"games", 
"advertise", 
"meta", 
"home", 
"gaming", 
"welcome" 
] 
var keyword = keywords[Math.floor(Math.random()*keywords.length)] 
document.write(keyword); 

No me gustaría ver una producción de:

meta, advertise, home, meta, gaming, welcome, ppc, welcome 

desde meta fue seleccionado por segunda vez antes de que todo había sido seleccionado una vez. me gustaría ver algo más como:.

meta, advertise, gaming,ppc, welcome, home, games, advertise, ppc, 

ya que este no ha seleccionado ninguna entrada varias veces antes de cada entrada había sido seleccionado al azar (el segundo bucle se inició en la segunda "anunciar" en caso de que no lo hiciste t coger las diferencias

Pero como puede ver en el código que he publicado anteriormente, no sé cómo hacerlo. He visto ejemplos en los que las entradas que se seleccionaron al azar, en realidad se eliminaron de la matriz en su totalidad, pero esto no es lo que quiero hacer. Solo quiero que cada entrada se seleccione una vez, y luego para reiniciar el proceso.

¿Alguien sabe el código para esto?

+0

posible duplicado de [serie de números al azar] (http://stackoverflow.com/questions/4373306/array-of-random-numbers) –

Respuesta

0

Si no te importa cambiar la matriz, puedes aleatorizar el orden de los elementos en la matriz y luego imprimir la matriz desde el primer elemento hasta el último.

O

Se podría hacer otra matriz de valores de 1 a N (donde n es el número de elementos). Aleatorice el orden de esa matriz y luego use eso como un índice para la matriz a medida que itera desde la primera hasta la última.

0

Almacene los números (índices) que ha visto en un hash, luego, cuando intente ver una nueva palabra, puede verificar el hash, si ya lo ha visto, genere un nuevo número. Asegúrese de verificar si la longitud del hash es la misma que la longitud de la matriz.

Esto evita la alteración de la matriz.

+0

Pero supongamos que tiene una serie de índices de 1000, la probabilidad de encontrar un índice único crecería exponencialmente con cada iteración. Para la última selección, tendría 1 en 1000 posibilidades de finalizar la función. Entonces, el ciclo iteraría 1000 veces extra, tal vez incluso más. Esto también se convierte en un problema cuando agrega índices. Su función de selección podría demorar varios minutos. – Krythic

+0

La mejor solución es elegir un índice aleatorio, luego cambiar ese índice al final de la matriz con el que seleccionó, y luego repetir nuevamente usando (array.Length - 1 - i) Se le garantiza una selección óptima de O/norte. – Krythic

5

Una forma muy simple de hacer esto sería usar splice cada vez que seleccione un elemento aleatorio y una vez que la matriz esté vacía, vuelva a llenarlo con los valores originales.

Ejemplo:

(function() { 
    var arr = []; 

    window.getRandomThing = function() { 
     if (arr.length === 0) { 
      refill(); 
     } 

     return arr.splice(Math.random() * arr.length, 1)[0]; 
    }; 

    function refill() { 
     arr = [1,2,3,4,5]; 
    } 
}()); 
2

se puede hacer una copia de la matriz original, a continuación, utilizar .splice() para tomar un valor en un índice de azar, y eliminar desde la matriz de copia.

Como la copia se está reduciendo en uno cada vez, simplemente puede hacerlo while(copy.length).

Ejemplo:http://jsfiddle.net/fMXTF/

var keywords = [ 
"ppc", 
"games", 
"advertise", 
"meta", 
"home", 
"gaming", 
"welcome" 
]; 

var copy = keywords.slice(); 

while(copy.length) { 

    var keyword = copy.splice(Math.floor(Math.random()*copy.length), 1); 
    document.write(keyword + '<br>'); 

} 

en cuenta que el número aleatorio se basa apagado copy.length, que, debido a la .splice(), se reduce en 1 en cada iteración. Por lo tanto, garantiza que el número aleatorio siempre se basa en actuallength de la copia.

+0

¡Esto funcionó muy bien para mí! Gracias. – Abdel

7

Puede usar la función Array.sort() para ordenarla aleatoriamente.

// random sort function 
function shuffle(a, b) 
{ 
    return Math.random() > 0.5 ? -1 : 1; 
} 

var keywords = ["ppc", "games", "advertise", "meta", "home", "gaming", "welcome"]; 

var randomKeywords = keywords.sort(shuffle); // new instance of a sorted randomly copy of the array 

alert(randomKeywords); 

actualización:

una mejor solución para barajar está utilizando Fisher-Yates aleatoria, como se encuentra en este answer.

function shuffle(array) 
 
{ 
 
    var m = array.length, t, i; 
 
    while (m > 0) 
 
    { 
 
\t i = Math.floor(Math.random() * m--); 
 
\t t = array[m]; 
 
\t array[m] = array[i]; 
 
\t array[i] = t; 
 
    } 
 
    return array; 
 
} 
 

 
var keywords = ["ppc", "games", "advertise", "meta", "home", "gaming", "welcome"]; 
 

 
shuffle(keywords); // shuffles the array 
 

 
alert(keywords);

+0

Esto no funciona para mí con Firefox y Opera en Linux. Necesito quitar el '-1' en' shuffle() '. Si la clase maneja '0' de la función de clasificación depende de la implementación, ¿qué tal' return (Math.random()> 0.5)? -1: 1; 'en el cuerpo de' shuffle() '? – sparklewhiskers

+0

Gracias, he actualizado la función de reproducción aleatoria. –

0

robados de user113716, pero optimizado un poco.

var arr = [ 
    "ppc", 
    "games", 
    "advertise", 
    "meta", 
    "home", 
    "gaming", 
    "welcome"]; 

Array.prototype.shuffle = Array.prototype.shuffle || function() { 
    var copy = this.slice(), arr = []; 
    while (copy.length) arr.push(copy.splice((Math.random() * copy.length) << 0)); 
    return arr; 
}; 

alert(arr.shuffle()); 
Cuestiones relacionadas