【问题标题】:shuffle JavaScript Array随机播放 JavaScript 数组
【发布时间】:2017-12-06 21:50:13
【问题描述】:

大家好。我正在制作一个记忆游戏,为了实现这一点,我不得不以某种方式对 Array 中的图像进行洗牌。我在 Stack Overflow 上找到了一个旧答案,Fisher–Yates shuffle,并使用了它,它有效,但我不明白如何。有人可以逐步解释这段代码中每个元素代表什么吗?特别是第一行,变量中如何存在三个值。谢谢。

function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

这样使用:

var arr = [2, 11, 37, 42];
arr = shuffle(arr);
console.log(arr);

【问题讨论】:

  • 第一行没有三个值,而是声明了 3 个不同的变量,其中只有第一个用数组长度初始化
  • 副本中的答案包括有关 Fisher-Yates 的资源。在更一般的说明中,由于该算法是众所周知的,您可以通过谷歌搜索以了解更多信息。它甚至还有一个维基百科页面。
  • var 关键字用于在给定范围内声明一个或多个变量(这里是 shuffle 函数范围)。做“var a, b, c;”本质上与执行“var a; var b; var c;”相同但更短。您可以使用“=”语法分配值,例如“var a = 'hello', b;”这又与 "var a = 'hello'; var b;" 相同

标签: javascript arrays shuffle


【解决方案1】:

把它分成几部分。假设数组长度为n。 我们从currentIndex = n 开始,一直持续到currentIndex = 0,这意味着所有元素都已被迭代并有可能移动到某个位置。

进入循环,第一行有两个函数

  • Math.random():在range [0, 1) 中生成一个随机实数。是的,它在 1 点打开,所以它永远不会生成 1
  • Math.floor():将实数的整数部分作为参数提供给它

现在观察,Math.random()*currentIndex 将在range [0, n) 中生成一个随机数(基本乘法)。 Math.floor() 将采用整数部分,因此我们将在 {0, 1, 2, ... n-1} 之间有一个整数。该值为randomIndex。

现在我们只是交换 currentIndex 和 randomIndex 的数字。我们从最后开始对所有元素执行此操作。所以数组被打乱了。

但是,这不是一个很好的洗牌算法,因为您正在减少每次迭代的随机性范围。更好的洗牌是将数字与随机数成对绑定,然后以这些绑定的随机数作为键对这些对进行排序,并摆脱它们以对原始数字数组进行洗牌。

【讨论】:

    【解决方案2】:
    var currentIndex = array.length, temporaryValue, randomIndex;
    

    一个变量中没有3个值,只有3个变量声明了一个初始化,其他是undefined。最好像这样格式化代码:

    var currentIndex = array.length,
        temporaryValue,
        randomIndex;
    

    while (0 !== currentIndex) {
        // ...
        currentIndex -= 1;
        // ...
    }
    

    currentIndex 从array.length 变为0,所以array.length 迭代


    randomIndex = Math.floor(Math.random() * currentIndex);
    

    0currentIndex - 1的随机数


    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
    

    交换位置randomIndexcurrentIndex的元素。

    这应该为您提供理解此代码的基础知识。

    【讨论】:

      【解决方案3】:

      第一行实际上只是写出三个变量的简写:

      所以,这个:

      var currentIndex = array.length, temporaryValue, randomIndex;
      

      翻译为:

      var currentIndex = array.length;   // 4
      var temporaryValue;                // undefined
      var randomIndex;                   // undefined
      

      【讨论】:

      • 呃,currentIndex 将是一个数字,而不是数组。
      • @vlaz 谢谢。很好的收获。
      【解决方案4】:
      <p id="result">
      
      <script>
      var arrayList= ['a','b','c','d','e','f','g'];
      arrayList.sort(function(){
          return 0.5 - Math.random()
      })
      
      document.getElementById("result").innerHTML  = arrayList;
      
      </script>
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
      猜你喜欢
      • 2011-01-27
      • 2019-04-03
      • 1970-01-01
      • 2023-01-23
      • 1970-01-01
      • 2011-07-02
      相关资源
      最近更新 更多