AS3 random array-рандомизировать массив-actionscript 3

Как рандомизировать массив с помощью actionscript 3?

8 ответов


существует короткая версия с использованием массива.функция сортировки ():

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 ) );

если вы не получите "достаточно" случайности, вы можете сортировать дважды:)

EDIT-объяснение строка за строкой:

на Array метод класса sort() вы можете передать не только параметры сортировки, как Array.CASEINSENSITIVE, Array.DESCENDING и так далее, но также и ваша собственная ссылка на функцию сравнения (обратный вызов), которая принимает два параметра (два элемента из массива Для сравнения). От AS3 документация:

функция сравнения должна принимать два аргумента для сравнения. Учитывая элементы A и B, результат compareFunction может иметь отрицательное, 0 или положительное значение:

  • отрицательное возвращаемое значение указывает, что A появляется перед B в отсортированной последовательности.
  • возвращаемое значение 0 означает, что A и B имеют одинаковый порядок сортировки.
  • положительное возвращаемое значение указывает, что A появляется после B в отсортированная последовательность.

Примечание: параметры функции сравнения могут быть набраны (если Ваш массив набран) и иметь любое имя, которое вы хотите, например.:

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

этот метод очень полезен, когда вам нужно отсортировать элементы массива по их особые свойства. В случае рандомизации compareFunction случайным образом возвращает -1, 0 или 1 и делает элементы массива для переключения их мест (индексов). Я обнаружил, что лучшая рандомизация (в моем субъективном и математически непроверенном мнение) - это когда метод возвращает только -1 и 1. Также имейте в виду, что функция сортировки с пользовательской функцией сравнения не сравнивает элементы последовательно таким образом, в некоторых особых случаях результаты рандомизации могут отличаться от того, что вы могли бы ожидать.


есть лучший способ, который также позволит вам рандомизировать массив на месте, если вам это нужно, и это не заставит вас создать более одной копии исходного массива.

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;
        }
    }
}

У меня было альтернативное требование, когда я хотел случайно вставить множество исходных массивов в целевой массив случайным образом. Как и Rytis, я большой поклонник функций forEach, map и sort на массивах.

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);

вот более простая функция. Работает также на многомерных массивах

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;
}

Я нашел это очень полезным. Надеюсь, вам это тоже поможет.

// 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 :)

Если вам нужно, чтобы Ваш массив был перетасован (ваши элементы не могут повторяться). Вы можете использовать эту функцию:

/**
 * 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;
}

использование:

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

вот как я рандомизирую свой массив из 36 карт для игры в память

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.............
}

выбрать случайную строку из массива

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;
}

использование:

trace(keyGenerator(16));