【问题标题】:Pick 15 random numbers put them shuffle them to not get duplicates选择 15 个随机数,将它们随机播放,以免重复
【发布时间】:2016-03-06 20:26:00
【问题描述】:

假设我在 1 到 12 之间选择 10 个随机数并将它们放入一个数组中。如何循环遍历它以消除重复?

我在这方面花了很多时间,但无法让它发挥作用。

【问题讨论】:

标签: javascript random shuffle


【解决方案1】:

如果您想要 15 个介于 1 和 20 之间且不重复的随机整数,那么这就是您范围内的大部分整数。我只会生成数字 1-20 并随机删除 15 次:

function randomIntegersInRange(min:int, max:int, count:uint):Array {
    if (min >= max || count > max - min) throw new ArgumentError("Invalid arguments!");
    var integers:Array = [];
    for (var i:int = min; i <= max; i++) {
        integers.push(i);
    }

    var randomIntegers:Array = [];
    for (i = 0; i < count; i++) {
        randomIntegers.push(integers.splice(Math.random() * integers.length, 1));
    }
    return randomIntegers;
}

randomIntegersInRange(1, 20, 15); // 16,4,3,13,8,17,1,19,20,15,6,18,14,10,12
randomIntegersInRange(1, 50, 20); // 27,3,19,9,42,23,13,29,11,24,41,31,26,2,7,30,49,33,6,10

注意:如果您想要大范围(例如 1 到 1,000,000 之间的 15 个整数),我不建议您这样做。

【讨论】:

  • 但是如果我想要随机数呢?比如说从 1 到 50,然后选择 20 而不重复?
  • 这会给你随机数。如果要参数化范围,只需将上面的2015 更改为变量即可。
  • @CollapsedSounds 将我的答案编辑为一个函数,其中包含范围和计数的参数。
  • 感谢您的回答。但是我还有一个问题。当我尝试调用此函数时,让我们从按钮中说“将值类型数组隐式强制转换为不相关类型函数”。我该如何处理?
  • 听起来你尝试了addEventListener("evt", randomIntegers(1, 20, 15)),但你需要传递一个函数作为处理程序,而不是调用一个函数。您可以从 addEventListener("evt", handler); function handler(e:Event):void { randomIntegers(1, 20, 15) } 之类的处理程序中调用此函数
【解决方案2】:

解决这个问题有两种方法:

创建一个随机数,检查它是否已经被选中,如果没有,将该值添加到输出中。

var numbers = [];
while(numbers.length < 10){
    var nr = Math.floor(Math.random() * 12)+1
    if(numbers.indexOf(nr) === -1) numbers.push(nr);
    else console.log("threw away ", nr);
}

这很好用,如果你想从大范围中选择少量数字, 因为在这里它可能会遇到很少的冲突(一遍又一遍地选择相同的随机数,然后不得不把它扔掉)。

在您的情况下,12 范围内的 10 个值,您很可能会有很多点击 在代码必须一遍又一遍地创建随机数以找到另一个的最后 尚未在您的集合中的号码。

所以我们进入第二种方法:创建一个包含所有可能值的集合,将其随机化, 然后从中取出一片。

//a helper to shuffle the array
function shuffle(arr){
    for(var i=arr.length; --i > 0; ){
        var j = Math.floor(Math.random() * i);
        var tmp = arr[j];
        arr[j] = arr[i];
        arr[i] = tmp;
    }
    return arr;
}

//a helper to create a sequence ov values
function range(from, to, step){
    step = Math.abs(+step) || 1;
    to = +to || 0;
    var i = +from || 0, out = [];
    if(i > to) while(i>to) out.push(i), i -= step;
    else while(i<to) out.push(i), i += step;
    return out;
}

var numbers = shuffle(range(1,13)).slice(0, 10);

如果您只需要大量值中的一小部分,这将导致开销很大

【讨论】:

    【解决方案3】:

    做一个递归的方法,

    function pushIt(arr){
     var idx:int;
     if(arr.length == 10){ return arr; }
     else { 
       idx = Math.floor(Math.random() * 12) + 1;
       if(arr.indexOf(idx) == -1){ arr.push(idx); } 
       return pushIt(arr);
     }
    }
    
    console.log(pushIt([]));
    

    【讨论】:

      【解决方案4】:

      [5, 1, 8, 4, 10, 9, 11, 2, 6, 7]

      function generateUniqueArray(length, rangeMax){
        var arr = [];
        while(arr.length < length) {
          var rand = Math.ceil(Math.random()*rangeMax);
          var isInArr = false;
          for(var i = 0; i<arr.length;i++){
            if(arr[i]===rand){
              isInArr = true;
              break;
            }
          }
          if (!isInArr){
            arr[arr.length]=rand;
          }
        }
        return arr;
      }
      
      console.log(generateUniqueArray(10,12));

      【讨论】:

      • generateUniqueArray(12, 10) 崩溃 ;)
      【解决方案5】:

      您可以将它们放入哈希(js 对象)中,然后返回哈希中的键:

      function getUniques(arr){
         var seen = {};
         arr.forEach(function(item){
           seen[item] = true;
         });
         return Object.keys(seen);
      }
      

      【讨论】:

        猜你喜欢
        • 2014-09-09
        • 2018-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-19
        • 1970-01-01
        • 2020-07-16
        • 2023-01-23
        相关资源
        最近更新 更多