jQuery Javascript:5 中的随机数,在使用完所有数之前不重复

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19351759/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:44:16  来源:igfitidea点击:

Javascript: Random number out of 5, no repeat until all have been used

javascriptjqueryrandomnumbersrepeat

提问by user2860129

I am using the below code to assign a random class (out of five) to each individual image on my page.

我正在使用下面的代码为我页面上的每个单独的图像分配一个随机类(五个)。

$(this).addClass('color-' + (Math.floor(Math.random() * 5) + 1));

It's working great but I want to make it so that there are never two of the same class in a row.

它工作得很好,但我想让它永远不会有两个相同的班级。

Even better would be if there were never two of the same in a row, and it also did not use any class more than once until all 5 had been used... As in, remove each used class from the array until all of them have been used, then start again, not allowing the last of the previous 5 and the first of the next 5 to be the same color.

更好的是,如果一行中从来没有两个相同的类,并且在使用所有 5 个类之前它也不会多次使用任何类......就像从数组中删除每个使用过的类,直到所有这些类已经使用过,然后重新开始,不允许前5个中的最后一个和下5个中的第一个是相同的颜色。

Hope that makes sense, and thanks in advance for any help.

希望这是有道理的,并在此先感谢您的帮助。

回答by jfriend00

You need to create an array of the possible values and each time you retrieve a random index from the array to use one of the values, you remove it from the array.

您需要创建一个包含可能值的数组,并且每次从数组中检索随机索引以使用其中一个值时,都将其从数组中删除。

Here's a general purpose random function that will not repeat until all values have been used. You can call this and then just add this index onto the end of your class name.

这是一个通用随机函数,在使用完所有值之前不会重复。您可以调用它,然后将此索引添加到类名的末尾。

var uniqueRandoms = [];
var numRandoms = 5;
function makeUniqueRandom() {
    // refill the array if needed
    if (!uniqueRandoms.length) {
        for (var i = 0; i < numRandoms; i++) {
            uniqueRandoms.push(i);
        }
    }
    var index = Math.floor(Math.random() * uniqueRandoms.length);
    var val = uniqueRandoms[index];

    // now remove that value from the array
    uniqueRandoms.splice(index, 1);

    return val;

}

Working demo: http://jsfiddle.net/jfriend00/H9bLH/

工作演示:http: //jsfiddle.net/jfriend00/H9bLH/



So, your code would just be this:

所以,你的代码就是这样的:

$(this).addClass('color-' + (makeUniqueRandom() + 1));


Here's an object oriented form that will allow more than one of these to be used in different places in your app:

这是一个面向对象的表单,它将允许在您的应用程序的不同位置使用多个这些:

// if only one argument is passed, it will assume that is the high
// limit and the low limit will be set to zero
// so you can use either r = new randomeGenerator(9);
// or r = new randomGenerator(0, 9);
function randomGenerator(low, high) {
    if (arguments.length < 2) {
        high = low;
        low = 0;
    }
    this.low = low;
    this.high = high;
    this.reset();
}

randomGenerator.prototype = {
    reset: function() {
        this.remaining = [];
        for (var i = this.low; i <= this.high; i++) {
            this.remaining.push(i);
        }
    },
    get: function() {
        if (!this.remaining.length) {
            this.reset();
        }
        var index = Math.floor(Math.random() * this.remaining.length);
        var val = this.remaining[index];
        this.remaining.splice(index, 1);
        return val;        
    }
}

Sample Usage:

示例用法:

var r = new randomGenerator(1, 9);
var rand1 = r.get();
var rand2 = r.get();

Working demo: http://jsfiddle.net/jfriend00/q36Lk4hk/

工作演示:http: //jsfiddle.net/jfriend00/q36Lk4hk/

回答by Johann Echavarria

You can do something like this using an array and the splicemethod:

您可以使用数组和splice方法执行类似操作:

var classes = ["color-1", "color-2", "color-3", "color-4", "color-5"];
for(i = 0;i < 5; i++){
  var randomPosition = Math.floor(Math.random() * classes.length);
  var selected = classes.splice(randomPosition,1);
  console.log(selected);
  alert(selected);
}

回答by Deepsy

var used = [];
var range = [0, 5];

var generateColors = (function() {
    var current;
    for ( var i = range[0]; i < range[5]; i++ ) {

        while ( used.indexOf(current = (Math.floor(Math.random() * 5) + 1)) != -1 ) ;
        used.push(current);
        $("   SELECTOR     ").addClass('color-' + current);
    }
});

回答by RobG

Just to explain my comment to jfriend00's excellent answer, you can have a function that returns the members of a set in random order until all have been returned, then starts again, e.g.:

只是为了解释我对 jfriend00 的优秀答案的评论,您可以使用一个函数以随机顺序返回集合的成员,直到所有成员都返回,然后重新开始,例如:

function RandomList(list) {
  var original = list;
  this.getOriginal = function() {
    return original;
  }
}

RandomList.prototype.getRandom = function() {
  if (!(this.remainder && this.remainder.length)) {
    this.remainder = this.getOriginal().slice();
  }
  return this.remainder.splice(Math.random() * this.remainder.length | 0,1);
}

var list = new RandomList([1,2,3]);

list.getRandom(); // returns a random member of list without repeating until all
                  // members have been returned.

If the list can be hard coded, you can keep the original in a closure, e.g.

如果列表可以硬编码,则可以将原始列表保存在闭包中,例如

var randomItem = (function() {
  var original = [1,2,3];
  var remainder;
  return function() {
    if (!(remainder && remainder.length)) {
      remainder = original.slice();
    }
    return remainder.splice(Math.random() * remainder.length | 0, 1);
  };
}());