如何随机化(随机播放)JavaScript 数组?

新手上路,请多包涵

我有一个这样的数组:

var arr1 = ["a", "b", "c", "d"];

如何随机化/随机播放?

原文由 Ali 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 767
2 个回答

事实上的无偏洗牌算法是 Fisher-Yates (aka 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);

有关所使用算法的 更多信息。

原文由 ChristopheD 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是 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 开始),从而跳过最后一个元素。

算法运行时间是 O(n)请注意,随机播放是就地完成的,因此如果您不想修改原始数组,请先使用 .slice(0) 复制它。


编辑: 更新到 ES6/ECMAScript 2015

新的 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]];
    }
}

原文由 Laurens Holst 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题