【Javascript】配列の順序のランダム入れ替え
問題
phpだと shuffle($array)で配列の内容をランダムな順序に入れ替えられるじゃないですか。
Javascriptでも配列の要素のランダム入れ替えってできる?
[0,1,2,3,4,5,6,7,8,9] → [4,6,8,0,9,3,7,1,2] のような感じ。
答え
shuffle()関数で配列の要素をシャッフルできるのは、便利機能満載、関数の塊のphpならではの風景。
JavascriptのArrayオブジェクトにshuffleはない。実装方法も考えて自分で作る必要がある。
乱数で重みをつけて並べ替える方法
var x = [0,1,2,3,4,5,6,7,8,9]; //配列xの各要素に乱数で重みをつける for (var i = 0, l = x.length; i < l; ++i) { x[i] = [x[i], Math.random()]; } //配列xを重みによってソートする x.sort(function(a, b){return a[1] - b[1];}); //配列xを元の形に戻したいので、重み部分のデータを取り除く for (var i = 0, l = x.length; i < l; ++i) { x[i] = x[i][0]; } //xの要素はランダムな順序に入れ替えられた alert(x);
シュワルツ変換というらしい。
Javascript1.6以降で、Array.mapメソッドがあれば1行で書ける。
var x = [0,1,2,3,4,5,6,7,8,9] x = x.map(function(a){return {weight:Math.random(), value:a}}) .sort(function(a, b){return a.weight - b.weight}) .map(function(a){return a.value}); alert(x);
var x = [0,1,2,3,4,5,6,7,8,9] x = x.map(function(a){return [a, Math.random()]}) .sort(function(a, b){return a[1] - b[1]}) .map(function(a){return a[0]}); alert(x);
Arrayのメソッドとして x.shuffle() のような呼び出し方をしたい場合は、以下のようにする。
Array.prototype.shuffle = function() { return this.map(function(a){return [a, Math.random()]}) .sort(function(a, b){return a[1] - b[1]}) .map(function(a){return a[0]}); } var x = [0,1,2,3,4,5,6,7,8,9]; alert(x.shuffle());
Fisher-Yatesというアルゴリズムを使った例
Array.prototype.shuffle = function() { var i = this.length; while(i){ var j = Math.floor(Math.random()*i); var t = this[--i]; this[i] = this[j]; this[j] = t; } return this; } var x = [0,1,2,3,4,5,6,7,8,9]; x.shuffle(); alert(x);
ランダム番目を取り出していく方法
Array.prototype.shuffle = function(){ var l = this.length; var a = this.concat(); var r = []; while(l) r.push(a.splice(Math.floor(Math.random() * l--), 1)); return r; } var x = [0,1,2,3,4,5,6,7,8,9]; y = x.shuffle(); alert(y);
コメント