número random de matemática sem repetir um número anterior

Não consigo encontrar uma resposta para isso, digamos que eu tenho isso:

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

Como faço para que o número random não se repita? Por exemplo, se o número random for 2, não quero que 2 saia novamente.

    Existem várias maneiras de conseguir isso.

    Solução A: Se o intervalo de números não for grande (digamos, menos de 10), você pode apenas acompanhar os números que você já gerou. Então, se você gerar uma duplicata, descarte-a e gere outro número.

    Solução B: Gera previamente os números randoms, armazena-os em um array e depois passa pelo array. Você poderia fazer isso pegando os números 1,2,...,n e depois embaralhá-los. Veja http://snippets.dzone.com/posts/show/849

     var randorder = shuffle([0,1,2,3,4,5,6]); var index = 0; setInterval(function() { $('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300); }, 300); 

    Solução C: acompanhe os números disponíveis em uma matriz. Aleatoriamente escolha um número. Remova o número do dito 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); 

    Você parece querer um número random não repetitivo de 0 a 6, de modo semelhante à resposta de tskuzzy:

     var getRand = (function() { var nums = [0,1,2,3,4,5,6]; var current = []; function rand(n) { return (Math.random() * n)|0; } return function() { if (!current.length) current = nums.slice(); return current.splice(rand(current.length), 1); } }()); 

    Ele retornará os números de 0 a 6 em ordem aleatória. Quando cada um tiver sido desenhado uma vez, ele será iniciado novamente.

    você poderia tentar isso?

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

    Geralmente, minha abordagem é criar uma matriz contendo todos os valores possíveis e:

    1. Escolha um número random < = o tamanho da matriz
    2. Remova o elemento escolhido da matriz
    3. Repita as etapas 1 a 2 até que a matriz esteja vazia

    O conjunto resultante de números conterá todos os seus índices sem repetição.

    Melhor ainda, talvez algo assim:

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

    Em seguida, basta percorrer os itens, porque o shuffle os terá randomizado e retirado, um de cada vez.

    Eu gosto da resposta de Neal, embora isso esteja implorando por alguma recursion. Aqui está em java, você ainda terá a idéia geral. Note que você atingirá um loop infinito se você extrair mais números que MAX, eu poderia ter corrigido isso, mas deixado como está para clareza.

    Editar: viu neal acrescentou um loop while para que funcione muito bem.

     public class RandCheck { private List numbers; private Random rand; private int MAX = 100; public RandCheck(){ numbers = new ArrayList(); 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()); } } } 

    não tenho certeza se é tarde demais, mas ainda gostaria de adicionar –

     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]; } } 

    isso basicamente usa timestamp (a cada milissegundo) para sempre gerar um número único.

    Aqui está uma correção simples, se um pouco rudimentar:

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

    Se o próximo número for o mesmo que o último simplesmente menos 1, a menos que o número seja 0 (zero) e configure-o para qualquer outro número dentro do seu conjunto (eu escolhi 7, o índice mais alto).

    Eu usei este método dentro da function de ciclo porque a única estipulação na seleção de um número era que ele não deveria ser o mesmo que o último.

    Não é a solução mais elegante ou tecnicamente talentosa, mas funciona 🙂

    você consegue fazer isso. Tenha uma matriz pública de chaves que você usou e confira com esta function:

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

    (function de: function javascript inArray )

    Então o que você pode fazer é:

     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); 

    Este código vai ficar preso depois de obter todos os sete números, então você precisa ter certeza de que existe depois de acabar com todos eles.