我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
当前回答
我在考虑在控制台上粘贴oneliner。sort的所有技巧都给出了错误的结果,下面是我的实现:
['Bob', 'Amy', 'Joy'].map((person) => `${Math.random().toFixed(10)}${person}`).sort().map((person) => person.substr(12));
但不要在生产代码中使用它,它不是最佳的,只适用于字符串。
其他回答
重建整个阵列,逐个将每个元素放在一个随机位置。
[1,2,3].reduce((a,x,i)=>{a.splice(Math.floor(Math.random()*(i+1)),0,x);return a},[])
变量ia=[1,2,3];var it=1000;var f=(a,x,i)=>{a.splice(Math.floor(Math.random()*(i+1)),0,x);返回a};var a=新数组(it).fill(ia).map(x=>x.reduce(f,[]));var r=新数组(ia.length).fill(0).map((x,i)=>a.reduce((i2,x2)=>x2[i]+i2,0)/it)console.log(“这些值应该相当相等:”,r);
我认为还没有人给出一个可以在不扩展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));}
编辑:此答案不正确
参见评论和https://stackoverflow.com/a/18650169/28234.这里留作参考,因为这种想法并不罕见。
对于小型阵列,一个非常简单的方法就是:
const someArray = [1, 2, 3, 4, 5];
someArray.sort(() => Math.random() - 0.5);
它可能效率不高,但对于小型阵列来说,这很好。这里有一个例子,你可以看到它有多随机(或不随机),以及它是否适合你的用例。
const resultsEl=document.querySelector(“#results”);const buttonEl=document.querySelector(“#trigger”);常量生成器数组和随机化=()=>{常量someArray=[0,1,2,3,4,5,6,7,8,9];someArray.sort(()=>Math.random()-0.5);return someArray;};const renderResultsToDom=(结果,el)=>{el.innerHTML=results.join(“”);};buttonEl.addEventListener('click',()=>renderResultsToDom(generateArray AndRandomize(),resultsEl));<h1>随机化</h1><button id=“trigger”>生成</button><p id=“results”>0 1 2 3 4 5 6 7 8 9</p>
费希尔·耶茨在javascript中洗牌。我在这里发表这篇文章是因为与这里的其他答案相比,使用两个实用函数(swap和randInt)澄清了算法。
function swap(arr, i, j) {
// swaps two elements of an array in place
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function randInt(max) {
// returns random integer between 0 and max-1 inclusive.
return Math.floor(Math.random()*max);
}
function shuffle(arr) {
// For each slot in the array (starting at the end),
// pick an element randomly from the unplaced elements and
// place it in the slot, exchanging places with the
// element in the slot.
for(var slot = arr.length - 1; slot > 0; slot--){
var element = randInt(slot+1);
swap(arr, element, slot);
}
}
Fisher Yates的这种变体稍微更有效,因为它避免了元素与自身的交换:
function shuffle(array) {
var elementsRemaining = array.length, temp, randomIndex;
while (elementsRemaining > 1) {
randomIndex = Math.floor(Math.random() * elementsRemaining--);
if (randomIndex != elementsRemaining) {
temp = array[elementsRemaining];
array[elementsRemaining] = array[randomIndex];
array[randomIndex] = temp;
}
}
return array;
}