QA@IT

JavaScriptで Array のシャッフルはどうやる?

5367 PV

JavaScriptで Array のシャッフルはどうやるのが良いでしょうか?

[1, 2, 3, 4].shuffle() // [4, 1, 3, 2]

というようなものです。

追記:ライブラリに依存せずにできるとベターです。

  • 非破壊的であれば
    Object.defineProperty(Array.prototype,"shuffle",{value:function(){
    b=[]
    while(this.length>0)b.push(this.splice(Math.floor(Math.random()*this.length),1))
    return b
    }});
    [1,2,3].shuffle()
    -

回答

underscore.jsで実装されているFisher–Yates shuffleはごく簡単なアルゴリズムです。

Array.prototype.shuffle=function() {
  var a=this.slice();
  for (var i=a.length-1;i>=0;i--) {
    var r=Math.floor(i*Math.random());
    var tmp=a[i];
    a[i]=a[r];
    a[r]=tmp;
  }; 
  return a;
};
function shuffle(a) {
  for (var i=a.length-1;i>=0;i--) {
    var r=Math.floor(i*Math.random());
    var tmp=a[i];
    a[i]=a[r];
    a[r]=tmp;
  }
  return a;
}
編集 履歴 (0)
  • ありがとうございます! -
  • prototypeではなくObject.defineProperty等を使ってメソッドを隠蔽することをオススメします -

てきとーなかんじで

[1, 2, 3, 4].sort(function(x,y) { return Math.random() - Math.random(); });

編集 履歴 (0)
  • ランダムネスが保証されるのかなとか、O(n long n) より速いやり方があったような、、、とか面倒なことを言わなければ、これで十分ですね。ところで x, y は不要かも? -
  • 真面目にやるならこれじゃダメだと思います。引数はいらないすね。ありがとうございます。 -

underscore.js で _.shuffle() するとよいと思います。

編集 履歴 (0)
  • ありがとうございます。今どき underscore ぐらい使っているよねということなのでしょうけど、ライブラリに依存しないやり方があるといいなぁと思ったりしていましたので、質問に条件を追記しました -
ウォッチ

この質問への回答やコメントをメールでお知らせします。