math random number without repeating a previous nu

2019-01-04 12:47发布

Can't seem to find an answer to this, say I have this:

setInterval(function() {
    m = Math.floor(Math.random()*7);
    $('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);

How do I make it so that random number doesn't repeat itself. For example if the random number is 2, I don't want 2 to come out again.

8条回答
疯言疯语
2楼-- · 2019-01-04 13:01

could you try that,

setInterval(function() {
    m = Math.floor(Math.random()*7);
    $('.foo:nth-of-type(' + m + ')').fadeIn(300);
}, 300);
查看更多
家丑人穷心不美
3楼-- · 2019-01-04 13:05

There are a number of ways you could achieve this.

Solution A: If the range of numbers isn't large (let's say less than 10), you could just keep track of the numbers you've already generated. Then if you generate a duplicate, discard it and generate another number.

Solution B: Pre-generate the random numbers, store them into an array and then go through the array. You could accomplish this by taking the numbers 1,2,...,n and then shuffle them.

shuffle = function(o) {
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

var randorder = shuffle([0,1,2,3,4,5,6]);
var index = 0;

setInterval(function() {
    $('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300);
}, 300);

Solution C: Keep track of the numbers available in an array. Randomly pick a number. Remove number from said array.

var randnums = [0,1,2,3,4,5,6];

setInterval(function() {
    var m = Math.floor(Math.random()*randnums.length);
    $('.foo:nth-of-type('+(randnums[m])+')').fadeIn(300);
    randnums = randnums.splice(m,1);
}, 300);
查看更多
混吃等死
4楼-- · 2019-01-04 13:07

you can do this. Have a public array of keys that you have used and check against them with this function:

function in_array(needle, haystack)
{
    for(var key in haystack)
    {
        if(needle === haystack[key])
        {
            return true;
        }
    }

    return false;
}

(function from: javascript function inArray)

So what you can do is:

var done = [];
setInterval(function() {
    var m = null;
    while(m == null || in_array(m, done)){
       m = Math.floor(Math.random()*7);
    }
    done.push(m);
    $('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);

This code will get stuck after getting all seven numbers so you need to make sure it exists after it fins them all.

查看更多
Bombasti
5楼-- · 2019-01-04 13:08

I like Neal's answer although this is begging for some recursion. Here it is in java, you'll still get the general idea. Note that you'll hit an infinite loop if you pull out more numbers than MAX, I could have fixed that but left it as is for clarity.

edit: saw neal added a while loop so that works great.

public class RandCheck {
    private List<Integer> numbers;
    private Random rand;
    private int MAX = 100;

    public RandCheck(){
        numbers = new ArrayList<Integer>();
        rand = new Random();
    }

    public int getRandomNum(){
        return getRandomNumRecursive(getRand());
    }

    private int getRandomNumRecursive(int num){
        if(numbers.contains(num)){
            return getRandomNumRecursive(getRand());
        } else {
            return num;
        }
    }

    private int getRand(){
        return rand.nextInt(MAX);
    }

    public static void main(String[] args){
        RandCheck randCheck = new RandCheck();

        for(int i = 0; i < 100; i++){
            System.out.println(randCheck.getRandomNum());
        }
    }
}
查看更多
Luminary・发光体
6楼-- · 2019-01-04 13:10

not sure if its too late, but would still like to add--

var RecordKeeper = {};

SRandom = function () {
    currTimeStamp = new Date().getTime();
    if (RecordKeeper.hasOwnProperty(currTimeStamp)) {
        RecordKeeper[currTimeStamp] = RecordKeeper[currTimeStamp] + 1;
        return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
    }
    else {
        RecordKeeper[currTimeStamp] = 1;
        return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
    }
}

this basically uses timestamp (every millisecond) to always generate a unique number.

查看更多
虎瘦雄心在
7楼-- · 2019-01-04 13:10

Here's a simple fix, if a little rudimentary:

if(nextNum == lastNum){
    if (nextNum == 0){nextNum = 7;} 
    else {nextNum = nextNum-1;}
}

If the next number is the same as the last simply minus 1 unless the number is 0 (zero) and set it to any other number within your set (I chose 7, the highest index).

I used this method within the cycle function because the only stipulation on selecting a number was that is musn't be the same as the last one.

Not the most elegant or technically gifted solution, but it works :)

查看更多
登录 后发表回答