【问题标题】:How do I avoid getting two of the same arrays when using Math.random?使用 Math.random 时如何避免获得两个相同的数组?
【发布时间】:2017-01-19 00:59:01
【问题描述】:

我正在玩一个网络应用程序,遇到了生成两个不同项目并避免两次获得相同项目的问题。

// ITEM 1
var item1 = [
  "i/itemname1.png",
  "i/itemname2.png",
  "i/itemname3.png"
];

var size = item1.length
var x = Math.floor(size*Math.random())

function getItem1() {
    document.getElementById("item1").src = item1[x];
}
getItem1();

// ITEM 2
var item2 = [
  "i/itemname1.png",
  "i/itemname2.png",
  "i/itemname3.png"
];

var size = item2.length
var x = Math.floor(size*Math.random())

function getItem2() {
    document.getElementById("item2").src = item2[x];
}
getItem2();

使用此代码,我有机会获得两个相同的项目。 我需要一个解决方案来避免这种情况。有什么想法吗?

【问题讨论】:

    标签: javascript arrays random


    【解决方案1】:

    跳过您已经生成的索引。

    // ITEM 1
    var item1 = [
      "i/itemname1.png",
      "i/itemname2.png",
      "i/itemname3.png"
    ];
    
    var size = item1.length
    var x = Math.floor(size*Math.random())
    
    function getItem1() {
        document.getElementById("item1").src = item1[x];
    }
    getItem1();
    
    // ITEM 2
    var item2 = [
      "i/itemname1.png",
      "i/itemname2.png",
      "i/itemname3.png"
    ];
    
    // changes start here:
    size = item2.length
    var x2 = Math.floor((size-1)*Math.random())
    if (x2 >= x) x2++ // skip `x`
    
    function getItem2() {
        document.getElementById("item2").src = item2[x2]; // <-- x2 here, not x
    }
    getItem2();
    

    【讨论】:

    • 你能不能这么好心,用我的代码给我一个例子?
    • if (x2 &gt;= x) x2++ 部分似乎不太合理。如果 x 是 2 并且 x2 也是 2(总体上 1:3 或 1:9 的赔率相当不错),那么它会将 x2 设置为3,items[3] 未定义。
    • @RobG x2 永远不会是 2,因为 (size-1) 是 2 而Math.random() 永远不会返回 1.0
    • @JacobKrall—好的,但是如果 xx2 为 1,那么您将 x2 偏置为 2,当它应该以相等的机会变为 0 或 2 时。此外,如果 x 为 0 且 x2 为 1,则 x2 更改为 2。不是真正随机的。
    • 酷。我认为这总结了为什么答案应该包括对它们如何工作的解释,而不仅仅是代码。 ;-)
    【解决方案2】:

    您可以使用以下方法:

    n = array.length
    
    1. Get an item (randomly) from the array (from 0 to n) -> index1.
    2. Swap the items in index1 with n
    3. n = n - 1
    4. Get an item (randomly) from the array (from 0 to n) -> index2.
    

    这两个项目会有所不同

    【讨论】:

      【解决方案3】:

      如果你对数组进行切片(在函数范围内创建一个重复数组),生成一个随机数并拼接数组,直到你有两个 unquie 项。

      function getRandom(listOfThings,numberOfItems){
          let newarray = listOfThings.slice();
          let returnarray = [];
          for(let count=1;count<numberOfItems;count++){
              let size = newarray.length
              let x = Math.floor(size*Math.random());
              returnarray.push(newarray.splice(x-1,1));
           }
           return returnarray;
      }
      

      【讨论】:

        【解决方案4】:

        如果它们相同,我认为您需要再次生成它

        function generateRandomExcept(except, len, tries) { 
            if(tries >= len) 
                return null; 
            tries++;
            var num = Math.floor(Math.random() * len);
            return (num === except) ? generateRandom(min, max) : num;
        }
        

        【讨论】:

        • 如果你太倒霉了,这将永远持续下去hhhhhhh
        • 您可以监控尝试次数。或者您可以从第二个数组中删除生成的元素。如果您的数组有很多元素,这将需要一些时间。这取决于你。
        【解决方案5】:
        let items = [
          'i/itemname1.png',
          'i/itemname2.png',
          'i/itemname3.png'
        ];
        
        /**
         * @param {Number} arr
         * @param {Number} n
         * @returns {Array} of length of n.
         */
        function getRandomFromArray(arr, n) {
          // Getting a copy of an array.
          arr = arr.slice();
          // Removing elements from the array as long as there are not only required n elements left.
          while(arr.length > n) {
            // Randomly removing element from the array.
            arr.splice(Math.floor(Math.random() * arr.length), 1);
          }
          return arr;
        }
        
        // Returns an array consisting of 2 elements.
        getRandomFromArray(items, 2);
        

        【讨论】:

          猜你喜欢
          • 2023-04-04
          • 2015-04-06
          • 2015-03-27
          • 2018-02-28
          • 1970-01-01
          • 2012-12-08
          • 2017-10-24
          • 2022-01-17
          • 2019-12-31
          相关资源
          最近更新 更多