如何从0-9生成4个随机非重复数字?

时间:2017-02-25 11:09:48

标签: javascript random

我希望从0-9得到一个随机数字,并将其弹出以便它不会重复但是我发现在第二个数字被推后它没有它已经没有了号码弹出。相反,弹出一些尚未选择的其他数字,为重复提供空间。



var yourNum = [],
  oppNum = [],
  choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

function chooseRandomNumber() {
  return choose[Math.floor(Math.random() * choose.length)];
}

for (var i = 0; i < 4; i++) {
  if (i === 0) {
    yourNum.push(chooseRandomNumber());
    if (yourNum[yourNum.length - 1] === 9) {
      choose.pop();
    } else {
      choose.splice(yourNum[0], 1);
    }
  } else if (i === 1) {
    yourNum.push(chooseRandomNumber());
    if (yourNum[yourNum.length - 1] === 9) {
      choose.pop();
    } else {
      choose.splice(yourNum[1], 1);
    }
  } else if (i === 2) {
    yourNum.push(chooseRandomNumber());
    if (yourNum[yourNum.length - 1] === 9) {
      choose.pop();
    } else {
      choose.splice(yourNum[2], 1);
    }
  } else if (i === 3) {
    yourNum.push(chooseRandomNumber());
    if (yourNum[yourNum.length - 1] === 9) {
      choose.pop();
    } else {
      choose.splice(yourNum[3], 1);
    }
  }
}

console.log(choose);
console.log(yourNum);
&#13;
&#13;
&#13;

6 个答案:

答案 0 :(得分:1)

function getRand(min, max, result) {
  result = result || [];
  
  if(result.length == 4) {
    return result;
  }
  
  var rand =  Math.floor(Math.random()*max) + min;
  
  if(result.indexOf(rand) === -1) {
    result.push(rand);
  }
  return getRand(min, max, result);
}

var result = getRand(1,9);
console.log(result);

答案 1 :(得分:1)

你的整个方法是复杂和无法实现的。

更好的方法:

//first we need a shuffle function
function shuffle(array){
    for(var i = array.length, j, tmp; i--; ){
        j = 0|(Math.random() * i);
        tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
    }
    return array;
}

//now let's define a sequence of possible values
var numset = [0,1,2,3,4,5,6,7,8,9];

//shuffle the sequence and take the first 4 values 
var fourRandomValues = shuffle(numset).slice(0,4);
console.log("four random values: " + fourRandomValues);

//doing this multiple times:
for(var values = []; values.length < 10;){
    //shuffle again, and take the values that are now at the beginning of this sequence
    values.push( shuffle(numset).slice(0,4) );
}
console.log("more random values: \n" + values.join("\n"));

修改

通过实现迭代器的类型来解决holi-java的方法,我将为ES6迭代器/生成器添加一种方法

由于发电机可以是无限的序列,我们需要考虑到这一点。我们通过缓冲有限数量的值并随机返回来做到这一点;基本上是一个混乱的价值框架。

function *shuffled(iterable, bufferSize = 256){
    var buffer, numValues = 0, randomIndex;
    if(Array.isArray(iterable) && iterable.length <= bufferSize){
        //an optimization for (small) Arrays:
        buffer = iterable.slice();
        numValues = iterable.length;
    }else{
        buffer = Array( bufferSize )
        for(var value of iterable){
            //push value from the iterable to the buffer
            buffer[numValues++] = value;
            
            //buffer is full, yield a random value
            if(numValues === bufferSize){
                //choose a random value from the buffer
                randomIndex = 0|(Math.random() * (numValues-1));
                //yield it
                yield buffer[randomIndex];
                
                //overwrite the value with the last index 
                //that's cheaper than pop() and splice()
                buffer[randomIndex] = buffer[--numValues];
            }
        }
    }
    //iterable doesn't provide any more values
    //flush the buffer in a random order
    while(numValues){
        randomIndex = 0|(Math.random() * (numValues-1));
        yield buffer[randomIndex];
        buffer[randomIndex] = buffer[--numValues];
    }
}

//every Array is a valid iterator
for(var v of shuffled([0,1,2,3,4,5,6,7,8,9])) 
    console.log(v);

这样我们可以在不首先缓存数组中的所有值的情况下对值流进行混洗。

  • pro:记忆效率高
  • 可能的问题:如果缓冲区变小,结果不再感觉随机,因为在序列后期生成的值根本无法完全转移到开始。你看到一些噪音,但它不再感觉随意了。

现在让我们跳进潜在的无限序列:

// *shuffled again, for this snippet
function *shuffled(iterable, bufferSize = 256){
    var buffer, numValues = 0, randomIndex;
    if(Array.isArray(iterable) && iterable.length <= bufferSize){
        buffer = iterable.slice();
        numValues = iterable.length;
    }else{
        buffer = Array( bufferSize )
        for(var value of iterable){
            buffer[numValues++] = value;
            if(numValues === bufferSize){
                randomIndex = 0|(Math.random() * (numValues-1));
                yield buffer[randomIndex];
                buffer[randomIndex] = buffer[--numValues];
            }
        }
    }
    while(numValues){
        randomIndex = 0|(Math.random() * (numValues-1));
        yield buffer[randomIndex];
        buffer[randomIndex] = buffer[--numValues];
    }
}

//creates an infinite sequence of numbers
function *count(){
    for(var index = 0; true;)
        yield index++;
}

//like limits a iterator but for iterators
function *take(n, iterator){
    for(var value of iterator){
        if(n-- > 0) yield value;
        else break;
    }
}

//create an (infinite) counter and convert it into a generator of shuffled values
//with a bufferSize of 256 entries (play a bit with that value)
var shuffledSequence = shuffled(count(), 256);
//to convert that into an Array we take the first 1000 values generated from that generator
var array = [...take(1000, shuffledSequence)];
//and log it
console.log(array.toString());

答案 2 :(得分:0)

你的意思如下:

function next() {
function all() {
    return [].concat(Array(10).fill(null).map(function (_, index) {
        return index;
    }));
}
function random(start, end) {
    return parseInt(Math.random() * (end + 1 - start)) + start;
}
var self = this;

self.all = self.all && self.all.length && self.all || all().sort(function(){
    return random(-1, 1);
});
return self.all.shift();}
var results=Array(4).fill(null).map(next);
console.log(results);

答案 3 :(得分:0)

我认为浏览器运行起来会更好。

&#13;
&#13;
var it = {
    next: function () {
        var self = this;
        self._all = self._all && self._all.length && self._all || self.shuffle(self.all());

        return self._all.shift();
    },
    all: function () {
        return [0,1,2,3,4,5,6,7,8,9];
    },
    random: function (start, end) {
        if (!end && end != 0) {
            end = start;
            start = 0;
        }
        return parseInt(Math.random() * (end + 1 - start)) + start;
    },
    shuffle: function (array) {
        var self = this;
        for (var i = array.length - 1; i > 0; --i) {
            self.swap(array, i, self.random(i));
        }
        return array;
    },
    swap: function (array, i, j) {
        var tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    },
    reset: function () {
        this._all = null;
    }
};
for (var i = 0; i < 10; i++) {
    var results=[];
    for(var n=0;n<4;n++) results.push(it.next());
    console.log("retain:"+it._all + '>>generated:' + results);
    it.reset();
}
&#13;
&#13;
&#13;

答案 4 :(得分:-1)

修改

choose数组中取出四个唯一数字。这就是你追求的目标吗?

&#13;
&#13;
var yourNum = [],
  oppNum = [],
  choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

function chooseRandomNumber() {
  return choose[Math.floor(Math.random() * choose.length)];
}

var rand;
for (var i = 0; i < 4; i++) {
  rand = chooseRandomNumber();
  yourNum.push(rand);
  choose.splice(choose.indexOf(rand), 1);
}

console.log(choose);
console.log(yourNum);
&#13;
&#13;
&#13;

旧方法:

&#13;
&#13;
var start = 0, end = 9;

function generate(count) {
  var nums = [],
    random;

  for (var i = 0; i < count; i++) {
    while (!random || nums.indexOf(random) !== -1) {
      random = Math.floor(Math.random() * (end + 1)) + start;
    }

    nums.push(random);
  }
  
  return nums;
}

console.log(
  generate(4)
);
&#13;
&#13;
&#13;

答案 5 :(得分:-1)

演示:

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

var yourNums = [];
var choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (var i = 0; i < 4; i++) {
  yourNums = yourNums.concat(choose.splice(getRandomInt(0, choose.length), 1))
}

console.log("yourNums is:")
console.log(yourNums);
console.log("===")
console.log("choose is:")
console.log(choose);