【问题标题】:How do I generate a non-repeating random from an array of number in JavaScript?如何从 JavaScript 中的数字数组生成非重复随机数?
【发布时间】:2020-03-31 05:57:36
【问题描述】:

让 arr = [2,3,5,7,9] arr[Math.floor(Math.random() * arr.length)]

arr[Math.floor(Math.random() * arr.length)] //5
arr[Math.floor(Math.random() * arr.length)] //2
arr[Math.floor(Math.random() * arr.length)] //9
arr[Math.floor(Math.random() * arr.length)] //9

9在这里重复,我如何确保随机数永远不会重复。

【问题讨论】:

  • 我不确定您在这里要做什么。生成后,您不能只从数组中删除数字吗?或者,您要确保永远不会连续生成相同的随机数。
  • 是的,我认为删除是正确的。我该如何移除?我想确保同一个数字永远不会重复。
  • 我投票结束,因为 @ubuntu7788 想要的实际上是一个洗牌并且已经有了答案
  • 注意:你可以将答案与generator function结合起来进行惰性评估

标签: javascript arrays


【解决方案1】:

解决方案 1 - 检查是否重复

var min_number = 0;
var max_number = 100;
var numbers_to_generate = 10; 
// Make sure numbers_to_generate < (max_number - min_number + 1);

var numbers = [];
while(numbers.length < numbers_to_generate){
    var number = Math.floor(Math.random() * (max_number - min_number)) + min_number;
    if(numbers.indexOf(number) === -1) {
        numbers.push(number);
    }
}
console.log(numbers);

解决方案 2 - 从数字池中随机获取

var min_number = 0;
var max_number = 100;
var numbers_to_generate = 10; 
// Make sure numbers_to_generate < (max_number - min_number)

var numbers = [];
var pool = Array.from(new Array(max_number-min_number), (x,i) => i + min_number);
while(numbers.length < numbers_to_generate){
    var number = pool.splice(Math.floor(Math.random() * (pool.length-1)), 1)[0];
    numbers.push(number);
}
console.log(numbers);

【讨论】:

  • 拼接是一项代价高昂的操作(所选元素后面的所有元素都必须滑动一个位置)。您可以改为选择最后一个元素并放置已删除元素的位置。
  • 您可以对indexOf 说同样的话并生成大量数字,但这不是重点。这两种解决方案的目标不是证明一种比另一种更快或更有效(这实际上取决于变量的值),而是一种比其他解决方案更具确定性。
【解决方案2】:

从数组中删除重复项的一些技巧/方法。

let arr = [1, 1, 2, 3, 3, 4, 5, 5, 6];
let uArr1 = [...new Set(arr)];
console.log(uArr1);
let uArr2 = arr.filter((val, ind) => arr.indexOf(val) === ind);
console.log(uArr2);

【讨论】:

    【解决方案3】:

    如果数组中的元素是唯一的,并且您需要许多(或全部)元素,一个简单的方法是:1)随机排列数组,2)首先选择 n 元素。

    如果你不需要他们中的许多人,洗牌整个阵列是多余的,而选择可以与洗牌混合:

     function randomOrder(L) {
         let data = L.slice(), count = L.length;
         return function() {
             if (count === 0) throw Error("No more values available");
             let j = Math.floor(Math.random()*count);
             let value = L[j];
             L[j] = L[--count];
             return value;
         };
     }
    

    如果元素不是唯一的,您还必须检查以前没有使用过相同的值;根据数组的大小以及要提取的元素数量,使用Set 对象来跟踪它们可能是有意义的:

     function randomOrderDistinct(L) {
         let data = L.slice(), count = L.length, used = new Set;
         return function() {
             for(;;) {
                 if (count === 0) throw Error("No more values available");
                 let j = Math.floor(Math.random()*count);
                 let value = L[j];
                 L[j] = L[--count];
                 if (!used.has(value)) {
                     used.add(value);
                     return value;
                 }
             }
         };
     }
    

    【讨论】:

      【解决方案4】:

      这是你要求的吗?

      let arr = [2,3,5,7,9]
      console.log("This is your arr " + arr)
      
      let unique = [];
      
      let numbers_to_generate = arr.length;
      
      let index;
      
      let i = 0;
      while(unique.length != numbers_to_generate){
      
          unique.push(arr[Math.floor(Math.random() * arr.length)]);
          index = arr.indexOf(unique[i]);
      
          arr.splice(index, 1)
      
          i++
      }
      console.log("This is unique " + unique)

      在这之后你只需要得到唯一的第一个元素,我真的不知道你想做什么

      【讨论】:

        猜你喜欢
        • 2014-11-10
        • 2014-11-19
        • 1970-01-01
        • 2014-04-25
        • 1970-01-01
        • 1970-01-01
        • 2015-03-26
        • 2011-11-24
        • 2013-04-06
        相关资源
        最近更新 更多