Cyberspace Nova

Randomize Array – Shuffle an array in Flash

June 15, 2007 · 19 Comments

After I’ve post solution for shuffling an array with Array.sort method which purspose was to just show what a sort function can be used for I am now posting solution which is best for doing a shuffle of an array. There were few discussions about it on the web.

I’ve made a little test to demonstrate speed of testing

There are 4 methods
First one is Array.sort, second is using splice and last two are basiclly the same, one beign prototype for array and second is plain function which returns an array.

Speed test returned following results (could vary a little bit but not spectacular):

For 1500 elements
Sort – 2216 ms
Splice – 8300 ms
Prototype – 16 ms
Return Function -15 ms

You can take test file here

Prototype function and return function code is :

Array.prototype.mixElements = function() {
var _length:Number = this.length, rn:Number, it:Number, el:Object;
for (it = 0; it<_length; it++) {
el = this[it];
this[it] = this[rn = random(_length)];
this[rn] = el;
}
}

function mixArray(array:Array):Array {
var _length:Number = array.length, mixed:Array = array.slice(), rn:Number, it:Number, el:Object;
for (it = 0; it<_length; it++) {
el = mixed[it];
mixed[it] = mixed[rn = random(_length)];
mixed[rn] = el;
}
return mixed;
}

Code is only for AS2 but it can be easily turned into AS3 code

Categories: Actionscript 2 · Actionscript 2.0 · Flash · Flash _ · Flex · Web developer

19 responses so far ↓

  • ptolemy.co.uk » Blog Archive » Shuffling Arrays 2 // June 15, 2007 at 6:19 pm | Reply

    [...] over the last day or so about shuffling arrays. The results are interesting. Mr Steel offers a better method of shuffling than the one that I suggested. He’s right. It is: it is faster, and no less good, at least by any [...]

  • ptolemy.co.uk » Blog Archive » Shuffling Arrays 3 // June 16, 2007 at 2:29 pm | Reply

    [...] his blog, Mr Steel suggested another shuffling function, which seems not to have the problems that the sort-based function has. Unfortunately, I have to [...]

  • Random array in AS2 & AS3 example using sort « Cyberspace Nova // June 28, 2007 at 8:02 am | Reply

    [...] EDIT: you can take a look at algo comparison, with source for much faster approach in new post [...]

  • JenUnderscore_ // January 17, 2008 at 8:29 pm | Reply

    Thanks! This was very helpful :)

  • Seth // February 13, 2008 at 2:52 pm | Reply

    I’m a novice when it comes to actionscript. I understand I can copy paste these examples, but I’m more interested in the logic behind what is going on. Is there anyone who has the time to write an explanation for at least one of the examples so I can apply this to anything I might need to do. Thank you!

  • Miquel Ozke // February 19, 2008 at 11:29 am | Reply

    AS3 version (sacrifying some millisecond to make it easier to read)

    private function randomArraySort(_array:Array):Array {
    var _length:Number = _array.length;
    var mixed:Array = _array.slice();
    var rn:Number;
    var it:Number;
    var el:Object;
    for (it = 0; it<_length; it++) {
    el = mixed[it];
    rn = Math.floor(Math.random() * _length);
    mixed[it] = mixed[rn];
    mixed[rn] = el;
    }
    return mixed;
    }

  • Tonypee // February 27, 2008 at 5:27 am | Reply

    Slightly smaller AS3 version:

    function randomizeArray(array:Array):Array {
    var l:Number = array.length-1;
    for (var it = 0; it<l; it++) {
    var r = Math.round(Math.random()*l)
    var tmp = array[it];
    array[it] = array[r];
    array[r] = tmp;
    }
    return array;
    }

  • meggannn // March 6, 2008 at 2:01 am | Reply

    what is a arraY??? PLZ CAN U TELL ME PLZ I NEED TO KNOW FOR A TEST OR HOMEWORK RATHER!!!! by meggannn

  • tori // March 27, 2008 at 5:19 pm | Reply

    excellent. many thanks to you.

  • Anders // June 11, 2008 at 10:53 am | Reply

    @Tonypee: You code modifies the original array, and sometimes returns an extra empty element.
    My version look like this:
    private function randomizeArray($array:Array):Array {
    var returnArray:Array = new Array();
    var orgArray:Array = $array.slice();
    while (orgArray.length > 0) {
    var r:uint = Math.floor(Math.random()*orgArray.length);
    returnArray.push(orgArray.splice(r, 1));
    }
    return returnArray;
    }
    It removes a random element from the array, and add it to another array. And keeps going until all elements have been randomized.

  • Brighton flash ninja // June 29, 2008 at 9:01 pm | Reply

    This is really useful thanks, i was also having problems with empty elements causing my array to have random errors though

  • FJGamer // February 15, 2009 at 12:38 am | Reply

    I was making a randomized questions quiz with randomized answers (including the correct answer for each question and four random answers), and I kept seeing it repeat answers. It was mind-boggling, but I figured it out. I was checking for the value rather than the index in the splice function. Took me hours to figure out what I was doing wrong! XD

  • Random Sort // February 28, 2009 at 1:03 am | Reply

    [...] arrays… not a big deal if you have small arrays, but if you need to randomize 1000’s of values this method is much faster than using Array.sort() This entry was posted in arrays, misc and tagged [...]

  • Hoss // March 19, 2009 at 1:56 am | Reply

    @Anders : Your code creates a multi-dimensional array because you are pushing the return of the splice which itself is an array. Here’s the fix.

    private function randomizeArray(srcArray : Array) : Array {
    var returnArray : Array = new Array();
    var orgArray : Array = srcArray.slice();
    while (orgArray.length > 0) {
    var r : uint = Math.floor(Math.random() * orgArray.length);
    returnArray.push(orgArray.splice(r, 1)[0]);
    }
    return returnArray;
    }

  • Tom Anderson // March 27, 2009 at 6:55 pm | Reply

    Actually, IMO, the Prototype function in the post above is not truly random, and is in fact what is called a poorly implemented Knuth shuffle…

    http://en.wikipedia.org/wiki/Shuffle#Poorly_implemented_Knuth_shuffles

    To achieve true randomness, the the cards must be randomly selected from the cards that have not yet been selected, rather than switching the card with any of the other cards, some of which have likely been switched already.

    The correction to make is simple:
    USE:
    mixed[it] = mixed[rn = it + random(_length - it)];

    NOT:
    mixed[it] = mixed[rn = random(_length)];

  • Tom Anderson // March 27, 2009 at 7:37 pm | Reply

    Sorry for multiple posts, but I’m excited to be getting times of under 1 ms for 1500 value arrays…

    Using “while” instead of “for”, as in the following function, reduces the processing time from 4 ms to 1 ms! So the stats are (Methods 1-4 are original, Method 5 is the while loop):

    Method 1, time: 718
    Method 2, time: 1957
    Method 3, time: 3
    Method 4, time: 4
    Method 5 (while), time: 1, sometimes 0!

    /////////////////////////

    function mixArray(array:Array):Array {
    var _length:Number = array.length, mixed:Array = array.slice(), rn:Number, it:Number, el:Object;
    while (it < _length) {
    el = mixed[it];
    mixed[it] = mixed[rn = it + random(_length - it)];
    mixed[rn] = el;
    it++;
    }
    return mixed;
    }

  • Davide Zanotti // April 2, 2009 at 10:24 pm | Reply

    This is my own solution: http://www.daveoncode.com/2009/01/08/implementing-arrayshuffle-in-actionscript/

    It’s only 3 lines of code and it works fine :)

  • me // November 13, 2009 at 1:42 am | Reply

    @Tom Anderson: Yeah it gives you 0-1ms cause it is undefined, so the code doesn’t even run…

    You need to change this line
    var _length:Number = array.length, mixed:Array = array.slice(), rn:Number, it:Number = 0, el:Object;

  • andy // November 13, 2009 at 11:00 am | Reply

    Thank you Mr. Steel for the elegant prototype-based solution!

Leave a Comment