【问题标题】:Math.random to never generate same number as other Math.random [duplicate]Math.random 永远不会生成与其他 Math.random 相同的数字 [重复]
【发布时间】:2018-07-08 15:53:11
【问题描述】:

我有 4 个 Math.random 生成器。每个从数组中挑选 1 个 X 对象。

  var randomItem1 = projects[Math.floor(Math.random()*projects.length)];
  var randomItem2 = projects[Math.floor(Math.random()*projects.length)];
  var randomItem3 = projects[Math.floor(Math.random()*projects.length)];
  var randomItem4 = projects[Math.floor(Math.random()*projects.length)];

如何编写一个函数来阻止 Math.random 生成与其他 Math.random 生成器相同的数字。

我的猜测: 创建一个循环通过var randomItem 1 till 4 的循环。如果它发现 1 个或多个输出相同,它将为 1 个或多个重复输出重新生成一个新输出。

还有其他建议吗?

编辑:这是一个网站。

【问题讨论】:

  • 随机排列数组(或索引数组)并选择 4。
  • 或采取一组并检查。
  • 一旦你选择了一些东西,就把它从数组中删除。

标签: javascript


【解决方案1】:

感谢这个有趣的问题。我总是用图书馆来做这类事情,所以弄清楚它很有趣。

var projects
var randomProjects

function getRandomProjects(projects, sampleSize) {
  var projectsClone = projects.slice();
  var randomItems = [];
  while (sampleSize--) {
    randomItems.push(
      projectsClone.splice(Math.floor(Math.random()*projectsClone.length), 1)[0]
    );
  }
  return randomItems;
}

projects = ['1st project', '2nd project', '3rd project', '4th project', '5th project', '6th project'];
randomProjects = getRandomProjects(projects, 4);

randomProjects.forEach(function(randomProject) {
  console.log(randomProject);
});

projectsClone.splice(...)projectsClone 中删除一个随机项目,并将其作为数组中的单个项目返回 ([<project>])。因此,在循环的下一次迭代中,无法再选择该值 (<project>)。

但是,如果您在生产代码中使用它,我建议您使用库。例如losdash's _.sampleSize(projects, 4)

【讨论】:

    【解决方案2】:

    更新

    删除了 Setfor 循环 等不需要的部分,并添加了 splice()。由于splice(),此函数将改变原始数组。在连续有序数字的数组上使用splice()(即使在洗牌之后)可以保证一组唯一的数字。


    /**
     * genRan(quantity, length)
     *
     * Need a given amount of unique random numbers.
     *
     * Given a number for how many random numbers are to be returned (@quantity) and a 
     * number that represents the range of consecutive numbers to extract the random 
     * numbers from (@length), this function will:
     *  - generate a full array of numbers with the length of @length
     *  - use shuffle() to shuffle the array to provide an array of randomly ordered numbers 
     *  - splices the first @quantity numbers of the shuffled array
     *  - returns new array of unique random numbers
     *
     * @param {Number} quantity      length of returned array.
     * @param {Number} length        length of an array of numbers. 
     * 
     * @return {Array} An array of unique random numbers.
     */
    


    演示

    Demo中评论的细节

    var qty = 4
    var len = 100;
    
    function genRan(quantity, length) {
      // Ensure that quantity is never greater than length
      if (quantity > length) {
        quantity = length;
      }
      // Create an array of consecutive numbers from 1 to N
      var array = Array.from({
        length: length
      }, (value, key = 0) => key + 1);
      // Run shuffle get the returned shuffled array
      var shuffled = shuffle(array);
      // return an array of N (quantity) random numbers 
      return shuffled.splice(0, quantity);
    }
    
    console.log(genRan(qty, len));
    
    /* shuffle utility 
    || Uses Fisher-Yates algorithm
    */
    function shuffle(array) {
      var i = 0;
      var j = 0;
      var temp = null;
      for (i = array.length - 1; i > 0; i -= 1) {
        j = Math.floor(Math.random() * (i + 1))
        temp = array[i];
        array[i] = array[j];
        array[j] = temp;
      }
      return array;
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-24
      • 2017-12-04
      • 2021-03-22
      • 1970-01-01
      相关资源
      最近更新 更多