我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
当前回答
可理解的洗牌数组元素的方法设arr1=[“a”,“b”,“c”,“d”];函数洗牌(数组){let currentIndex=array.length;while(currentIndex!=0){let randomIndex=Math.floor(Math.random()*array.length);当前索引-=1;let temp=数组[currentIndex];array[currentIndex]=array[randomIndex];array[randomIndex]=临时;}返回数组;}设arr2=洗牌(arr1);arr2.forEach(元素=>console.log(元素));
其他回答
使用ES2015,您可以使用此功能:
Array.prototype.shuffle = function() {
let m = this.length, i;
while (m) {
i = (Math.random() * m--) >>> 0;
[this[m], this[i]] = [this[i], this[m]]
}
return this;
}
用法:
[1, 2, 3, 4, 5, 6, 7].shuffle();
使用Fisher Yates shuffle算法和ES6:
// Original array
let array = ['a', 'b', 'c', 'd'];
// Create a copy of the original array to be randomized
let shuffle = [...array];
// Defining function returning random value from i to N
const getRandomValue = (i, N) => Math.floor(Math.random() * (N - i) + i);
// Shuffle a pair of two elements at random position j
shuffle.forEach( (elem, i, arr, j = getRandomValue(i, arr.length)) => [arr[i], arr[j]] = [arr[j], arr[i]] );
console.log(shuffle);
// ['d', 'a', 'b', 'c']
首先,在这里查看javascript中不同排序方法的视觉比较。
其次,如果您快速查看上面的链接,您会发现与其他方法相比,随机顺序排序的性能似乎相对较好,同时实现起来非常简单和快速,如下所示:
function shuffle(array) {
var random = array.map(Math.random);
array.sort(function(a, b) {
return random[array.indexOf(a)] - random[array.indexOf(b)];
});
}
编辑:正如@gregers所指出的,比较函数是用值而不是索引来调用的,这就是为什么需要使用indexOf的原因。注意,由于indexOf在O(n)时间内运行,此更改使代码不太适合较大的数组。
NEW!
更短,可能更快的Fisher Yates洗牌算法
它使用while---按位到底数(最多10个十进制数字(32位))移除了不必要的封盖和其他东西
function fy(a,b,c,d){//array,placeholder,placeholder,placeholder
c=a.length;while(c)b=Math.random()*(--c+1)|0,d=a[c],a[c]=a[b],a[b]=d
}
脚本大小(以fy作为函数名):90字节
演示http://jsfiddle.net/vvpoma8w/
*可能在除chrome之外的所有浏览器上都更快。
如果您有任何问题,请提问。
EDIT
是的,它更快
性能:http://jsperf.com/fyshuffle
使用排名靠前的函数。
编辑计算过多(不需要--c+1),没有人注意到
更短(4字节)和更快(测试!)。
function fy(a,b,c,d){//array,placeholder,placeholder,placeholder
c=a.length;while(c)b=Math.random()*c--|0,d=a[c],a[c]=a[b],a[b]=d
}
在其他地方缓存var rnd=Math.random,然后使用rnd()也会稍微提高大数组的性能。
http://jsfiddle.net/vvpoma8w/2/
可读版本(使用原始版本。这会更慢,vars是无用的,像closures&“;”,代码本身也更短……也许读一下如何“缩小”Javascript代码,顺便说一句,你不能像上面那样用Javascript缩小器压缩以下代码。)
function fisherYates( array ){
var count = array.length,
randomnumber,
temp;
while( count ){
randomnumber = Math.random() * count-- | 0;
temp = array[count];
array[count] = array[randomnumber];
array[randomnumber] = temp
}
}
Fisher Yates的另一个实现,使用严格模式:
function shuffleArray(a) {
"use strict";
var i, t, j;
for (i = a.length - 1; i > 0; i -= 1) {
t = a[i];
j = Math.floor(Math.random() * (i + 1));
a[i] = a[j];
a[j] = t;
}
return a;
}