2012-08-16 16 views

Respuesta

17

hay una versión corta utilizando la función Array.sort():

var arr : Array = [0,1,2,3,4,5,6,7,8,9]; 

function randomize (a : *, b : *) : int { 
    return (Math.random() > .5) ? 1 : -1; 
} 

trace(arr.sort(randomize)); 

Si no se obtiene "suficiente" aleatoriedad se puede ordenar dos veces :)

EDITAR - explicación línea por línea:

Para Array clase método sort() puede pasar no solo ordenar opciones como Array.CASEINSENSITIVE, Array.DESCENDING, etc., pero también su propia referencia de función de comparación personalizada (una devolución de llamada) que acepta dos parámetros (dos elementos del conjunto para comparar). De la documentación AS3:

Una función de comparación debe tomar dos argumentos para comparar. Dado los elementos A y B, el resultado de comparar función puede tener un valor negativo, 0 o positivo:

  • Un valor de retorno negativo especifica que A aparece antes de B en la secuencia ordenada.
  • Un valor de retorno de 0 especifica que A y B tienen el mismo orden de clasificación.
  • Un valor de retorno positivo especifica que A aparece después de B en la secuencia ordenada.

Nota: compara los parámetros de función podrían ser tecleado (si se escribe la matriz) y tener cualquier nombre que desee, por ejemplo .:

function compareElements (elementA : SomeClass, elementB : SomeClass) : int; 

Este método es muy útil cuando se necesita para ordenar gama elementos por sus propiedades especiales. En el caso de aleatorización compareFunction se devuelve aleatoriamente -1, 0 o 1 y se crean elementos de matriz para cambiar sus lugares (índices). He encontrado que una mejor aleatorización (en mi opinión subjetiva y matemáticamente no probada) es cuando el método devuelve solo -1 y 1. También tenga en cuenta esa función de clasificación con la función de comparación personalizada doesn't compare elements sequentially, por lo que en algunos casos especiales los resultados de la aleatorización pueden diferir de lo que cabría esperar.

+2

Creo '(Math.random() <.5)? -1: 1' es mejor. – Florent

+0

De acuerdo, más eficiente y no hay necesidad de redondear – BadFeelingAboutThis

+0

Esto es bastante IMPRESIONANTE. ¿Puedes analizar las líneas y explicar lo que están haciendo? Al igual que lo que es (a: *, b: *) y el tipo, etc. –

1

Encontré esto muy útil. Espero que pueda ayudarte también.

// Array to Randomize 
var firstArray:Array = ["One","Two","Three","Four","Five","six","seven","eight","nine","ten"]; 
trace(firstArray); // Prints in order 

var newArray:Array = new Array(); 
function randomizeArray(array:Array):Array 
{ 
    var newArray:Array = new Array(); 

    while (array.length > 0) 
    { 
     newArray.push(array.splice(Math.floor(Math.random()*array.length), 1)); 
    } 

    return newArray; 
} 

var randomArray:Array = randomizeArray(firstArray); 
trace(randomArray); // Prints out randomized :) 
2

Hay una mejor manera de que también le permitirá asignar al azar a la matriz en su lugar, si necesita eso, y que no hará que se crea más de una sola copia de su matriz original.

package 
{ 
    import flash.display.Sprite; 

    public class RandomizeArrayExample extends Sprite 
    { 
     public function RandomizeArrayExample() 
     { 
      super(); 
      testDistribution(); 
     } 

     private function testDistribution():void 
     { 
      var hash:Object = { }; 
      var tester:Array = [1, 2, 3, 4]; 
      var key:String; 

      for (var i:int; i < 1e5; i++) 
      { 
       randomize(tester); 
       key = tester.join(""); 
       if (key in hash) hash[key]++; 
       else hash[key] = 1; 
      } 
      for (var p:String in hash) trace(p, "=>", hash[p]); 
     } 

     private function randomize(array:Array):Array 
     { 
      var temp:Object; 
      var tempOffset:int; 
      for (var i:int = array.length - 1; i >= 0; i--) 
      { 
       tempOffset = Math.random() * i; 
       temp = array[i]; 
       array[i] = array[tempOffset]; 
       array[tempOffset] = temp; 
      } 
      return array; 
     } 
    } 
} 
1

Tenía un requisito alternativo en el que quería insertar aleatoriamente muchas matrices fuente en una matriz de destino aleatoriamente. Al igual que Rytis, soy un gran admirador de las funciones de ForEach, map and sort en Arrays.

var randomInsert:Function = function callback(item:*, index:int, array:Vector.<MyItem>):void 
{ 
    var j:Number = Math.floor(Math.random() * targetArray.length); 
    targetArray.splice(j,0,item);     
} 

targetArray = new Vector.<MyItem>(); 
sourceArray1.forEach(randomInsert, this); 
sourceArray2.forEach(randomInsert, this); 
1

aquí es una función más fácil. Funciona también en matrices multidimensionales

function randomizeArray(array:Array):Array 
{ 
    var newArray:Array = new Array(); 
    while (array.length > 0) 
    { 
     var mn=Math.floor(Math.random()*array.length) 
     newArray[newArray.length]=array[mn] 
     array.splice(mn,1) 
    } 
    return newArray; 
} 
0

Si necesita reorganizar su matriz (sus elementos no pueden repetirse).Se podría utilizar esta función:

/** 
* Shuffles array into new array with no repeating elements. Simple swap algorithm is used. 
*/ 
public function shuffleArray(original:Array):Array 
{ 
    // How many swaps we will do 
    // Increase this number for better results (more shuffled array, but slower performance) 
    const runs:int = original.length * 3; 
    var shuffled:Array = new Array(original.length); 

    var i:int; 
    var a:int; 
    var b:int; 
    var temp:Object; 

    // Copy original array to shuffled 
    for(i=0; i<shuffled.length; i++){ 
     shuffled[i] = original[i]; 
    } 

    // Run random swap cycle 'runs' times 
    for(i=0; i<runs; i++){ 
     // There is a chance that array element will swap with itself, 
     // and there is always small probability it will make your shuffle 
     // results not that good, hence try to experiment with 
     // different runs count as stated above 
     a = Math.floor(Math.random() * original.length); 
     b = Math.floor(Math.random() * original.length); 

     // Swap messages 
     temp = shuffled[a]; 
     shuffled[a] = shuffled[b]; 
     shuffled[b] = temp; 
    } 

    return shuffled; 
} 

Uso:

var testArray:Array = ["Water", "Fire", "Air", "Earth"]; 
trace(shuffleArray(testArray).concat()); 
0

así es como me RANDOMIZE mi serie de 36 cartas para un juego de memoria

const QUANT_CARTAS: int = 36; 

//get the 36 numbers into the array 
for (var i: int = 0; i < QUANT_CARTAS; i++) 
{ 
    cartas.push(i); 
} 

//shuffles them =) 
for (var moeda: int = QUANT_CARTAS - 1; moeda > 0; moeda--) 
{ 
    var pos: int = Math.floor(Math.random() * moeda); 
    var carta: int = cartas[moeda]; 
    cartas[moeda] = cartas[pos]; 
    cartas[pos] = carta; 
} 
// and add them using the random order... 

    for (i = 0; i < QUANT_CARTAS; i++) 
{ 
    var novaCarta: Carta = new Carta(); 
    novaCarta.tipoCarta = cartas[i]; 
    etcetcetc............. 
} 
0

eligen cadena aleatoria de la matriz

function keyGenerator(len:Number):String 
{ 
    function randomRange(minNum:Number, maxNum:Number):Number 
    { 
     return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum); 
    } 
    var hexArray = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']; 
    var key = ""; 
    for (var i=0; i<len; i++) 
    { 
     key += hexArray[randomRange(0,hexArray.length-1)]; 
    } 
    return key; 
} 

uso:

trace(keyGenerator(16)); 
Cuestiones relacionadas