【问题标题】:Get random value from array excluding previously chosen从数组中获取随机值,不包括先前选择的值
【发布时间】:2018-02-19 13:24:11
【问题描述】:

我已经开始使用 Javascript 构建一个超级基本的“常识测验”......但我正在努力想出一种有效的方法来获取一个不包括先前选择的问题的随机问题。

目前我有一个名为 previous_questions 的数组,它存储先前选择的问题的索引,以及一个 while 循环,如果数字已经存在,则继续为 'r' 生成随机值previous_questions 数组。

var r = Math.floor(Math.random() * questions.length);
while(previous_questions.indexOf(r) >= 0) {
    r = Math.floor(Math.random() * questions.length);
}

虽然目前这正在起作用,但我无法想象这是一种有效的方法,并且当没有问题可供选择时可能会导致无限循环。什么是更有效的方法?提前致谢!

【问题讨论】:

    标签: javascript arrays loops random


    【解决方案1】:

    实现此目的的一种方法是随机排列问题,而不是一次选择随机问题。

    function shuffle(a) {
      for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
      }
      return a;
    }
    
    let questions = ["a", "b", "c", "d", "e", "f"];
    
    shuffle(questions); /* Shuffle the question array */
    
    //Looping thru the shuffled questions
    questions.forEach(q => {
        console.log(q);
    });

    洗牌功能被拍here

    【讨论】:

      【解决方案2】:

      有很多方法可以做到这一点。一种方法是有 2 个数组,1 个包含所有未问的问题,另一个包含所有已问的问题。您使用从 1 到 n 的随机数(未问问题数组的大小)选择一个问题,然后将该问题从未问问题列表中删除,并将其放入已问问题列表中。这样你就永远不会陷入无限循环,事实上你每次迭代只需要得到一个随机数。如果您无法改变未提出问题的数组,那么您可以在操作开始时对数组进行克隆,然后使用该克隆执行您想要的操作。

      【讨论】:

        【解决方案3】:

        你可以复制数组,然后随机删除元素:

        const left = questions.slice();
        
        function getQuestion(){
          if(!left.length) return;
        
          return left.splice(Math.floor(Math.random() * left.length), 1)[0];
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-10-12
          • 2013-08-31
          • 2012-01-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多