如何随机化(随机排列)一个JavaScript数组?
2022-08-29 21:57:10
我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
如何随机化/随机播放?
我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
如何随机化/随机播放?
事实上的无偏洗牌算法是Fisher-Yates(又名Knuth)Shuffle。
您可以在此处看到出色的可视化效果(以及与此链接的原始帖子))
function shuffle(array) {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle.
while (currentIndex != 0) {
// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
// Used like so
var arr = [2, 11, 37, 42];
shuffle(arr);
console.log(arr);
以下是 Durstenfeld shuffle 的 JavaScript 实现,这是 Fisher-Yates 的优化版本:
/* Randomize array 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;
}
}
它为每个原始数组元素选择一个随机元素,并将其从下一次抽奖中排除,就像从一副纸牌中随机挑选一样。
这种巧妙的排除将选取的元素与当前元素交换,然后从其余元素中选取下一个随机元素,向后循环以获得最佳效率,确保简化随机选取(它始终可以从 0 开始),从而跳过最后一个元素。
算法运行时为 。请注意,随机播放是就地完成的,因此,如果您不想修改原始数组,请先使用 .slice(0)
复制它。O(n)
新的ES6允许我们一次分配两个变量。当我们想要交换两个变量的值时,这特别方便,因为我们可以在一行代码中完成。下面是使用此功能的相同函数的较短形式。
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]];
}
}