**Update**: *my Vector shuffle function will not work with Vector.<int>. Please read AS3 Object shuffle or randomize for an improved and more generic shuffleObject function.*

In almost all tools we develop for Gynzy and bord.nl the questions are randomized. When searching the net for a generic function to shuffle Actionscript Vectors, I couldn’t find any. That’s why I wrote this article and a shuffleVector function.

It all started with shuffling Arrays. My colleague Mathijs showed me this article about Fisher-Yates shuffling: it’s efficient both in runtime and space and the result is really random.

Mathijs translated the example Python code into Actionscript and I added some comments:

/** * Shuffles array with Fisher-Yates shuffling * using com.gskinner.utils.Rndm class * @param arr * example: ArrayUtils.shuffleArray(myArray); */ public static function shuffleArray(arr:Array):void{ if (arr.length > 1){ var i:int = arr.length - 1; while (i > 0) { var s:Number = Rndm.integer(0, arr.length); var temp:* = arr[s]; arr[s] = arr[i]; arr[i] = temp; i--; } } } |

But what I really needed was a function to shuffle any kind of Vector. So I took the function above and changed it into this:

/** * Shuffles Vector with Fisher-Yates shuffling * using com.gskinner.utils.Rndm class * @param vec * example: VectorUtils.shuffleVector(myVector as Vector.<*>); */ public static function shuffleVector(vec:Vector.<*>):void{ if (vec.length > 1){ var i:int = vec.length - 1; while (i > 0) { var s:Number = Rndm.integer(0, vec.length); var temp:* = vec[s]; vec[s] = vec[i]; vec[i] = temp; i--; } } } |

For me, it’s very convenient to have one function for shuffling all my Vectors. The only improvement I can think of is the “`as Vector.<*>`

” part when calling the function: `VectorUtils.shuffleVector(myVector as Vector.<*>);`

If you have any suggestions to make this function call more elegant, please let me know.

**Note:** *We use com.gskinner.utils.Rndm class because it generates random numbers based on a seed number: necessary if you have to reproduce a random output.
If you don’t have or want to use this class, change line 11
*

`var s:Number = Rndm.integer(0, vec.length);`

into
`var s:Number = Math.round(Rndm.random()*(inVector.length-1));`

`var s:Number = Math.round(Math.random()*(vec.length));`

Note: We use com.gskinner.utils.Rndm class because it generates random numbers based on a seed number: necessary if you have to reproduce a random output.

If you don’t have or want to use this class, change line 11

var s:Number = Rndm.integer(0, vec.length);

into

var s:Number = Math.round(Rndm.random()*(inVector.length-1));

again Rndm!!! And “inVector”

Hey, I came across the same Vector shuffle issue around the time you did too Here’s was my solution:

http://www.milkisevil.com/blog/2010/as3-vector-shuffle-randomize/

In think yours will be more efficient as I’m just hijacking the vector sort method.

By the way, I tried casting a Vector.int to Vector.*, but the vector becomes null within the shuffle method. So did this actually work for you?

Great article!

I noticed there is a slight typo in the last line of this post.

Math.round(Rndm.random()*(inVector.length-1));

should be

Math.round(Math.random()*(inVector.length-1));

Mike, thanks for noticing my typo. I changed the last line of code like you suggested.

Thanks for the great code snippet! I was looking for a good way to shuffle a Vector.

Thanks for the code. Nice help.

But seems like there’s still a typo at:

var s:Number = Math.round(Math.random()*(vec.length));

Where it should read:

var s:Number = Math.round(Math.random()*(vec.length-1));

or

var s:Number = Math.floor(Math.random()*(vec.length));

Hi dSilva, you’re right. You can find the updated code in this article:

http://www.bonth.nl/2011/05/29/as3-object-shuffle-or-randomize/

[…] 参考元 http://www.bonth.nl/2010/07/25/as3-vector-shuffle-or-randomize/ […]

I don’t think

var s:Number = Math.round(Math.random()*(vec.length));

will work.

First of all, since you use round(), getting 0th index is half as likely as getting any other valid index.

Secondly, it Math.random produces Number close to 1, you will get index out of bounds exception because if you have 5 elements in vector then Math.round(0.999*5) = 5 which will cause to access element with index 5 which is not there.

Use this one instead:

var s:Number = Math.floor(Math.random()*(vec.length));

Hi miniml, please have a look at my other blogpost for an improved and more generic shuffleObject function. I use Math.floor in that post.

http://www.bonth.nl/2011/05/29/as3-object-shuffle-or-randomize/