About
This is an implementation of a non-standard array generic method, shuffle, using the Fisher-Yates algorithm.
Usage
Add the following script to the head of your HTML document:
<script src="path_to/shuffle.js"></script>
Examples
// standard
console.log(
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].shuffle()
);
// generic
console.log(
Array.shuffle([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
);
Methods
Available as generic and standard:
Mutator |
---|
shuffle |
Implementation Notes
Random Numbers
To get a nice even ditribution when generating a random number within a specific range we use:
var n = Math.floor(Math.random() * (max - min)) + min;
For our purposes min is always 0, so the previous line becomes:
var n = Math.floor(Math.random() * max);
And using a little rounding trick, we gain a speed advantage:
var n = Math.random() * max | 0;
Array Generics
When creating the generic version of the shuffle method we chain two Function
prototypes together.
First we use Function.apply()
to change the this
reference to Array.prototype.shuffle()
and pass the values from the array-like arguments
object as individual parameters to Function.call()
.
Array.shuffle([0, 1, 2]);
// internally calls ...
Array.prototype.shuffle.call.apply(Array.prototype.shuffle, arguments);
// which roughly translates to ...
Array.prototype.shuffle.call(Array.protoype.shuffle, [0, 1, 2]);
This mind-bending approach is used instead of something like slicing the arguments object with Array.slice()
and passing those values to Function.call()
to allow JavaScript engines like V8 to continue to optimize the code.