2009-05-02 28 views
8

He creado un sitio para un artista amigo mío, y ella quiere que el diseño siga siendo el mismo, pero también quiere que las nuevas pinturas que ha producido se mezclen en el diseño actual. Así que tengo 12 miniaturas (thumb1 - thumb12) en la página principal de la galería y 18 imágenes (img1 - img18) para colocar también¿Aleatorizar elementos en una matriz?

El enfoque que pensé fue crear una matriz de todas las imágenes, aleatorizarla, luego simplemente raspe los primeros 12 y cárguelos en las ranuras para los pulgares. Otro enfoque sería seleccionar 12 imágenes al azar de la matriz. En el primer caso, no puedo encontrar una forma de aleatorizar los elementos de una matriz. En este último caso, no puedo entender cómo evitar que las imágenes se carguen más de una vez, aparte de usar una segunda matriz, lo que parece muy ineficiente y aterrador.

Estoy haciendo todo esto en Javascript, por cierto.

+0

posible duplicado de [Cómo selecciona aleatoriamente una matriz de JavaScript?] (Http://stackoverflow.com/questions/2450954/how- to-randomize-a-javascript-array) – Bergi

Respuesta

18

Escribí esto hace un tiempo y parece que se ajusta a lo que está buscando. Creo que es el Algoritmo Fisher-Yates que ojblass se refiere a:

Array.prototype.shuffle = function() { 
    var i = this.length; 
    while (--i) { 
     var j = Math.floor(Math.random() * (i + 1)) 
     var temp = this[i]; 
     this[i] = this[j]; 
     this[j] = temp; 
    } 

    return this; // for convenience, in case we want a reference to the array 
}; 

Tenga en cuenta que la modificación Array.prototype puede ser considerado de mala educación. Es posible que desee implementar esto como un método independiente que toma la matriz como un argumento. De todos modos, para acabar con él:

var randomSubset = originalArray.shuffle().slice(0,13); 

O, si no se desea modificar realmente el original:

var randomSubset = originalArray.slice(0).shuffle().slice(0,13); 
+0

Tenga en cuenta que el bucle interno es la mezcla de Fisher-Yates mencionada. El ciclo externo está haciendo mezclas múltiples. (No es que haya nada de malo en eso.) –

+2

Solo anote su ciclo 'iters'. La mezcla de Fisher-Yates se dice que es imparcial, lo que significa que cada permutación es igualmente probable. Mezclar la matriz varias veces de ninguna manera "significa una mejor mezcla". –

+0

¿Incluso si el número aleatorio tiene una distribución muy desigual? También puedo editar esa parte de todos modos, ya que ofusca la respuesta a la pregunta, como señala Bill. –

1

Su primer enfoque funcionaría. Simplemente mezcle los 18 elementos y tome los primeros 12.

1

Recientemente me encontré con este problema a mí mismo. La publicación aquí ayudó: http://waseemsakka.com/2012/02/14/javascript-dropping-the-last-parts-of-an-array-and-randomizing-the-order-of-an-array/.

Básicamente, se inicia mediante la aleatorización de su matriz:

thumbs.sort(function(a, b) { 
    return Math.random() - 0.5; 
}) 

Esto aleatorizar el orden de los 18 elementos. A continuación, sólo para mantener a los primeros 12 elementos, que acaba de caer el último 6:

thumbs.length = 12; 
+0

La mayoría de las funciones de ordenamiento que he visto requieren que la función de comparación sea coherente, y los resultados no se definen si no lo son.Pude imaginar resultados aleatorios que arrojaban la función de ordenación a un ciclo infinito si mantenía la reorganización de los elementos que creía tener en el orden correcto (aunque esto probablemente no ocurra en la práctica). –

Cuestiones relacionadas