JavaScript で 配列 を シャッフル する 方法

0 件のコメント

配列を ランダム に シャッフル する アルゴリズム は Fisher-Yates法 というものが有名なようなので、それを JavaScript 向けに実装してみました。 元々の配列(Array)を拡張する方法、jQuery を拡張する方法もあわせて掲載しています。

Fisher-Yates法

Fisher-Yates シャッフル は Knuth シャッフル としても知られているものだそうです。 最初の考案は 1938年 にもさかのぼる古いもののようです。

基本コード

まずは純粋に基本となるコードを掲載します。 これを元にした、配列(Array) の拡張、jQuery の拡張は後に記載します。

/**
* 指定された配列を Fisher–Yates法 で シャッフルします。
* (注意:引数に渡した配列自体をシャッフルします。)
* @param    number[]    arr     シャッフルしたい配列
* @return   number[]    シャッフルされた配列
*/
var shuffle = function (arr) {
    var i, j, tmp, length;

    for (length = arr.length, i = length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    return arr;
};

配列(Array)の機能拡張として shuffle メソッド を追加する方法

配列自体を拡張したい場合、上記のメソッドを Array のプロトタイプへ設定すれば可能となります。 いわゆる prototype拡張 といったところです。 配列を引数として取らない代わりに、this を利用しているところがポイントです。

Array.prototype.shuffle = function () {
    var i, j, tmp, length;

    for (length = this.length, i = length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        tmp = this[i];
        this[i] = this[j];
        this[j] = tmp;
    }

    return this;
};

jQuery の プラグイン として shuffle メソッド を追加する方法

jQuery に shuffle メソッド を拡張する場合、プラグインとして機能追加します。 具体的には以下のようなコードになります。

jquery.shuffle.js

(function (window, document, $, undefined) {
    $.fn.shuffle = function () {
        var i, j, tmp, length;

        for (length = this.length, i = length - 1; i > 0; i--) {
            j = Math.floor(Math.random() * (i + 1));
            tmp = this[i];
            this[i] = this[j];
            this[j] = tmp;
        }

        return this;
    };
})(window, document, jQuery);

ちなみに、上記の jQuery.shuffle を利用して、リスト(li)をシャッフルするコード(HTML と JavaScript)は以下のようになります。

<ul id='list'>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>
$('#list li').shuffle().appendTo('#list');

参考記事