【问题标题】:Javascript unique random number generator is not generating unique numbersJavascript唯一随机数生成器不生成唯一数字
【发布时间】:2018-05-03 15:25:24
【问题描述】:

我正在尝试一个新的随机数生成器,它应该生成没有重复的数字,但是当我尝试将它应用到我的页面时,它会产生许多重复。至少有 60% 的时间存在重复,一次重复三次,两次重复。

我正在尝试来自 Generate unique random numbers between 1 and 100 的答案,即使我将其限制为 20 个数字,它似乎也能正常工作。以零重复数字运行 40 次。当我试图把它放在我现有的函数中时,它就会分崩离析。知道我在这里缺少什么吗?这是我之前的问题Fill table with random images的延续@

/* The part of what each image url has in common
   ⍟ var base = 'images/Image_'
   */
var base = 'images/Image_';
var suff = '.jpg';

function randomCellBG(base) {

  // Reference the <table>
  var T = document.getElementById('mainTable');

  /* Collect all .cell into a NodeList and convert
  || it into an array
  */
  var cellArray = Array.from(T.querySelectorAll('.cell'));

  // map() the array; run a function on each loop...
  cellArray.map(function(cel, idx) {

    // Get a random number 1 - 9
    var arr = []
    while (arr.length < 9) {
      var ran = Math.ceil(Math.random() * 40)
      if (arr.indexOf(ran) > -1) continue;
      arr[arr.length] = ran;
    }

    /* Concatenate base and random number to form
    || a string of a url of an image
    ⍟ result: "images/Image_08.jpg"
    */
    var img = base + ran.toString() + suff;

    /* Assign that url as the value to the 
    || backgroundImage property of the .cell
    || in current iteration
    */
    cel.innerHTML = "<img src='" + img + "'/>";

  });

}

【问题讨论】:

  • 您正在为cellArray 中的每个项目生成一组新的 5 个唯一随机数。这些集合之间可能存在重叠。旁注:如果您真正想做的是.forEach,请避免使用.map。它们有不同的用途。
  • 抱歉,在用一组受限的数字测试了代码的执行情况后,忘记改回代码了。我想从一组 40 个中选择 9 个。
  • 你应该在cellArray.map之前生成随机数,而不是在里面

标签: javascript random duplicates


【解决方案1】:

如果我理解正确,那么您需要: 1. 将 map 更改为 forEach 2. 您需要将保存已生成数字的数组移出 forEach 函数 3. 更改数字生成器循环

/* The part of what each image url has in common
⍟ var base = 'images/Image_'
*/
var base = 'images/Image_';
var suff = '.jpg';

function randomCellBG(base) {

  // Reference the <table>
  var T = document.getElementById('mainTable');

  /* Collect all .cell into a NodeList and convert
  || it into an array
  */
  var cellArray = Array.from(T.querySelectorAll('.cell'));

  // initialize the array
  var arr = []
  // map() the array; run a function on each loop...
  cellArray.forEach(function (cel, idx) {

    // generate numbers 1-40 and check if they were already generated
    do {
      var ran = Math.ceil(Math.random() * 40)
    } while (arr.indexOf(ran) > -1);
    //save the newly generated unique number
    arr[arr.length] = ran;

    /* Concatenate base and random number to form
    || a string of a url of an image
    ⍟ result: "images/Image_08.jpg"
    */
    var img = base + ran.toString() + suff;

    /* Assign that url as the value to the 
    || backgroundImage property of the .cell
    || in current iteration
    */
    cel.innerHTML = "<img src='" + img + "'/>";
  });
}

【讨论】:

    【解决方案2】:

    为什么不打乱数组,然后取出表格所需的前 n 个项目?

    您可以使用 shuffle 算法,然后简单地切片图像表所需的元素。

    Shuffle 表示使用随机函数不会产生重复。

    类似的东西:

    function shuffleArray(array) {
        array.forEach(function(e, i) {
            exch(array, i, Math.floor(Math.random() * (i + 1)));
        });
        function exch(array, i, j) {
            const temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
    }
    
    var array = [0, 1, 2, 3, 4, 5, 6, 7, 8];
    shuffleArray(array);
    console.log(array.slice(0, 3));
    
    array = ["a", "b", "c", "d", "e", "f"];
    shuffleArray(array);
    console.log(array.slice(0, 3));

    【讨论】:

      【解决方案3】:

      看起来您需要做的是生成随机数,然后然后将它们应用到每个单元格:

      function generateNumbers(count, upperBound) {
          if (count > upperBound) { throw new Error('count cannot be more than upper bound'); }
      
          var arr = []
      
          while (arr.length < count) {
            var ran = Math.ceil(Math.random() * upperBound)
            if (arr.indexOf(ran) > -1) continue;
            arr[arr.length] = ran;
          }
      
          return arr;
      }
      
      function randomCellBG(base) {
      
        // Reference the <table>
        var T = document.getElementById('mainTable');
      
        /* Collect all .cell into a NodeList and convert
        || it into an array
        */
        var cellArray = Array.from(T.querySelectorAll('.cell'));
      
        var nums = generateNumbers(cellArray.length, 40);
      
        // map() the array; run a function on each loop...
        cellArray.forEach(function(cel, idx) {
          /* Concatenate base and random number to form
          || a string of a url of an image
          ⍟ result: "images/Image_08.jpg"
          */
          var img = base + nums[idx] + suff;
      
          /* Assign that url as the value to the 
          || backgroundImage property of the .cell
          || in current iteration
          */
          cel.innerHTML = "<img src='" + img + "'/>";
      
        });
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-03-13
        • 1970-01-01
        • 1970-01-01
        • 2020-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多