我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
当前回答
$=(m)=>控制台日志(m);//----将此方法添加到Array类Array.prototype.shuffle=函数(){return this.sort(()=>.5-Math.random());};$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());
其他回答
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;
}
所有其他答案都基于Math.random(),它很快,但不适用于密码级别的随机化。
下面的代码使用了众所周知的Fisher Yates算法,同时利用Web Cryptography API实现了随机化的加密级别。
变量d=[1,2,3,4,5,6,7,8,9,10];函数洗牌(a){var x,t,r=新Uint32Array(1);对于(var i=0,c=a.length-1,m=a.length;i<c;i++,m-){crypto.getRandomValues(r);x=数学楼层(r/65536/65536*m)+i;t=a[i],a[i]=a[x],a[x]=t;}返回a;}console.log(shuffle(d));
只是为了在馅饼里插一根手指。在这里,我介绍了Fisher Yates shuffle的递归实现(我认为)。它给出了统一的随机性。
注意:~~(双颚化符运算符)实际上与正实数的Math.floor()类似。这只是一条捷径。
var shuffle=a=>a.length?a.splice(~~(Math.random()*a.length),1).contat(shuffle(a)):a;console.log(JSON.stringify(shuffle([0,1,2,3,4,5,6,7,8,9]));
编辑:由于使用了.splice(),上面的代码是O(n^2),但我们可以通过交换技巧消除O(n)中的拼接和混洗。
var shuffle=(a,l=a.length,r=~~(Math.random()*l))=>l?([a[r],a[l-1]]=[a[l-1],a[r]],shuffle(a,l-1)):a;var arr=Array.from({length:3000},(_,i)=>i);console.time(“shuffle”);洗牌(arr);console.timeEnd(“shuffle”);
问题是,JS无法与大型递归合作。在这种特殊的情况下,数组大小会受到限制,大约为3000~7000,这取决于浏览器引擎和一些未知的事实。
使用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
我认为还没有人给出一个可以在不扩展Array原型的情况下连接起来的解决方案(这是一个糟糕的做法)。使用稍微鲜为人知的reduce(),我们可以轻松地以允许串联的方式进行混洗:
var randomsquares = [1, 2, 3, 4, 5, 6, 7].reduce(shuffle).map(n => n*n);
您可能希望传递第二个参数[],否则如果尝试在空数组上执行此操作,则会失败:
// Both work. The second one wouldn't have worked as the one above
var randomsquares = [1, 2, 3, 4, 5, 6, 7].reduce(shuffle, []).map(n => n*n);
var randomsquares = [].reduce(shuffle, []).map(n => n*n);
让我们将shuffle定义为:
var shuffle = (rand, one, i, orig) => {
if (i !== 1) return rand; // Randomize it only once (arr.length > 1)
// You could use here other random algorithm if you wanted
for (let i = orig.length; i; i--) {
let j = Math.floor(Math.random() * i);
[orig[i - 1], orig[j]] = [orig[j], orig[i - 1]];
}
return orig;
}
您可以在JSFiddle或此处看到它的实际应用:
var shuffle=(all,one,i,orig)=>{如果(i!==1)返回全部;//你可以在这里使用其他随机算法for(设i=原始长度;i;i-){设j=数学地板(Math.random()*i);[原始[i-1],原始[j]]=[原始[j],原始[i-1]];}返回原点;}对于(变量i=0;i<5;i++){var randomarray=[1,2,3,4,5,6,7]。reduce(shuffle,[]);console.log(JSON.stringify(randomarray));}