我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
当前回答
从理论的角度来看,在我看来,最优雅的方法是得到一个介于0和n之间的随机数-并计算从{0,1,…,n!-1}到(0,1、2,…,n-1)的所有置换的一对一映射。只要你能使用一个足够可靠的(伪)随机发生器来获得这样一个数字而没有任何明显的偏差,你就有足够的信息来实现你想要的,而不需要其他几个随机数。
当使用IEEE754双精度浮点数计算时,您可以期望随机生成器提供大约15个小数。既然你有15岁=1307674368000(带13位数字),您可以对最多包含15个元素的数组使用以下函数,并假设最多包含14个元素的阵列不会有明显的偏差。如果您正在处理一个固定大小的问题,需要多次计算该洗牌操作,您可能需要尝试以下代码,因为它只使用Math.random一次(但它涉及多次复制操作),因此可能比其他代码更快。
下面的函数不会被使用,但我还是给出了它;它根据此消息中使用的一对一映射(枚举排列时最自然的映射)返回给定排列(0,1,2,…,n-1)的索引;它打算与多达16个元件一起工作:
function permIndex(p) {
var fact = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000];
var tail = [];
var i;
if (p.length == 0) return 0;
for(i=1;i<(p.length);i++) {
if (p[i] > p[0]) tail.push(p[i]-1);
else tail.push(p[i]);
}
return p[0] * fact[p.length-1] + permIndex(tail);
}
上一个函数的倒数(您自己的问题需要)如下:;它打算与多达16个元件一起工作;它返回(0,1,2,…,s-1)的n阶排列:
function permNth(n, s) {
var fact = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000];
var i, j;
var p = [];
var q = [];
for(i=0;i<s;i++) p.push(i);
for(i=s-1; i>=0; i--) {
j = Math.floor(n / fact[i]);
n -= j*fact[i];
q.push(p[j]);
for(;j<i;j++) p[j]=p[j+1];
}
return q;
}
现在,你想要的只是:
function shuffle(p) {
var fact = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000];
return permNth(Math.floor(Math.random()*fact[p.length]), p.length).map(
function(i) { return p[i]; });
}
它应该适用于多达16个元素,但有一点理论偏差(尽管从实际角度看不明显);它可以被视为完全可用于15个元件;对于包含少于14个元素的数组,您可以放心地认为绝对没有偏差。
其他回答
//one line solution
shuffle = (array) => array.sort(() => Math.random() - 0.5);
//Demo
let arr = [1, 2, 3];
shuffle(arr);
alert(arr);
https://javascript.info/task/shuffle
Math.random()-0.5是一个随机数,可以是正数或负,所以排序函数会随机地重新排序元素。
您可以通过以下方式轻松完成:
//阵列var fruits=[“香蕉”、“橙色”、“苹果”、“芒果”];//随机的,随机的fruits.sort(函数(a,b){return 0.5-Math.random()});//输出console.log(水果);
请参考JavaScript排序数组
可理解的洗牌数组元素的方法设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(元素));
使用array.splice()随机化数组
function shuffleArray(array) {
var temp = [];
var len=array.length;
while(len){
temp.push(array.splice(Math.floor(Math.random()*array.length),1)[0]);
len--;
}
return temp;
}
//console.log("Here >>> "+shuffleArray([4,2,3,5,8,1,0]));
demo
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;
}