【问题标题】:Fisher–Yates Shuffle in JavascriptJavascript 中的 Fisher-Yates Shuffle
【发布时间】:2016-10-12 01:51:12
【问题描述】:

JS 新手,目前正在大学学习。对于我目前的 JS 项目,我正在构建一个记忆卡游戏。我开始思考如何随机洗牌,我接近了 Fisher-Yates Shuffle 算法所做的事情——this page 上的第二个程序。但是,我不明白 [0] 在拼接方法之后究竟做了什么。是移动/压缩数组的原因吗?如果是,我找不到其他相关示例/文档。

function shuffle(array) {
  var copy = [], n = array.length, i;

  // While there remain elements to shuffle…
  while (n) {

    // Pick a remaining element…
    i = Math.floor(Math.random() * n--);

    // And move it to the new array.
    copy.push(array.splice(i, 1)[0]);
  }

  return copy;
}

【问题讨论】:

    标签: javascript arrays shuffle splice


    【解决方案1】:

    array.splice(i, 1) 截取arrayi-th 元素并将其作为单值数组返回(就像array.splice(i, 2) 将截取i-th 和i+1-th 元素和将它们作为二元素数组返回)。然后[0],简单的索引操作,从该数组中选择单个元素(因为我们不需要数组);然后使用copy.push 将此单个元素添加到copy

    更熟悉的索引操作用法:

    array = [4, 7, 2, 10];
    array[0]
    // => 4
    array[1]
    // => 7
    
    array = [18];
    array[0]
    // => 18
    

    【讨论】:

    • 谢谢@Amadan!
    • 所以我对此进行了更多思考。我不明白的是,对我来说,[0] 是多余的,因为我们只从数组中取出一个元素,因为拼接的范围是 (i, 1)
    • splice 返回一个数组。 push 想要一个值。单元素数组与其元素不同。这就像试图在你的搅拌机中放入一个装有番茄的网袋,并争辩说“好吧,我需要一个番茄来做这种酱汁,而袋子里只剩下一个番茄,那为什么不呢?”。你需要先把番茄从袋子里拿出来,因为那些塑料网状纤维有点耐嚼。
    • 我现在明白了。非常感谢@Amadan
    • @Amadan 听起来很简单,而且可能很愚蠢,这个比喻——混合番茄——必须是我听过的对单个元素数组和元素本身之间区别的最好解释.太棒了,谢谢。 :-)
    【解决方案2】:

    array.splice() 返回一个数组,但在洗牌时,您想从未知位置随机取出一张牌并将其放入新数组中(洗牌后的一张)。现在要注意的是,您不想通过 copy.push(array.splice(i, 1) 再次添加类似的数组,因为这会将整个返回的数组添加到复制数组中,并且随机播放的随机性会降低,这反过来会导致游戏中的相关结果因为该数组将与最后一个相似(~),只是翻转了几位。将[0] 添加到array.splice(i, 1) 可确保您只从一次返回的整个结果数组中复制一个元素,从而产生更大的随机性。

    【讨论】:

    • 谢谢@Cyclotron3x3,现在说得通了。非常感谢。
    • 我不明白的是随机性是由随机数i 产生的,它将选择数组的随机索引进行拼接,然后将结果推送到最后新数组copy,因此最终新数组元素的整个索引将是随机的(每次迭代都会将元素推入数组末尾)。那么[0]在这里不是多余的吗?
    猜你喜欢
    • 2019-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2011-03-21
    相关资源
    最近更新 更多