我有一個像這樣的數組: 算法
var arr1 = ["a", "b", "c", "d"];
如何隨機/隨機播放? 數組
一我的能夠(或應該)將其用做Array的原型: dom
來自ChristopheD: 優化
Array.prototype.shuffle = function() { var i = this.length, j, temp; if ( i == 0 ) return this; while ( --i ) { j = Math.floor( Math.random() * ( i + 1 ) ); temp = this[i]; this[i] = this[j]; this[j] = temp; } return this; }
這是Durstenfeld shuffle的JavaScript實現, Durstenfeld shuffle是Fisher-Yates的計算機優化版本: ui
/** * Randomize array element order in-place. * Using Durstenfeld shuffle algorithm. */ function shuffleArray(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } }
Fisher-Yates算法的工做原理是爲每一個原始數組元素選擇一個隨機元素,而後從下一個繪製中將其排除。 就像從一副紙牌中隨機挑選同樣。 this
這種排除方法是巧妙的方法(由Durstenfeld發明,供計算機使用),方法是將選擇的元素與當前元素交換,而後從其他元素中選擇下一個隨機元素。 爲了得到最佳效率,循環會向後運行,從而簡化了隨機選擇(它始終能夠從0開始),而且因爲沒有其餘選擇,它會跳過最後一個元素。 spa
該算法的運行時間爲O(n)。 請注意,隨機播放是就地完成的。 所以,若是您不想修改原始數組,請首先使用.slice(0)
對其進行復制。 .net
新的ES6容許咱們一次分配兩個變量。 當咱們要交換兩個變量的值時,這特別方便,由於咱們能夠在一行代碼中完成它。 這是使用此功能的相同功能的縮寫。 prototype
function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } }
使用underscore.js庫。 在這種狀況下,方法_.shuffle()
很合適。 這是該方法的示例: code
var _ = require("underscore"); var arr = [1,2,3,4,5,6]; // Testing _.shuffle var testShuffle = function () { var indexOne = 0; var stObj = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5 }; for (var i = 0; i < 1000; i++) { arr = _.shuffle(arr); indexOne = _.indexOf(arr, 1); stObj[indexOne] ++; } console.log(stObj); }; testShuffle();
添加到@Laurens Holsts答案。 這是50%壓縮的。
function shuffleArray(d) { for (var c = d.length - 1; c > 0; c--) { var b = Math.floor(Math.random() * (c + 1)); var a = d[c]; d[c] = d[b]; d[b] = a; } return d };
var shuffle = function(array) { temp = []; originalLength = array.length; for (var i = 0; i < originalLength; i++) { temp.push(array.splice(Math.floor(Math.random()*array.length),1)); } return temp; };