Olá Patrick, tudo bem com você?
Então, realmente existe um erro de lógica no seu código que cria um loop infinito até que o navegador trave, mas vou te explicar com calma :)
Temos um exemplo até bem parecido em nosso curso de lógica, mas o problema esta nessa verificação:
if(numero == sequencia[posicao]){
break;
}else{
sequencia.push(numero);
calc++;
}
Vamos fazer o que chamamos de teste de mesa
, que é testar o nosso código em uma folha de papel:
Vamos supor que chamamos a função inserirNoArray(3)
, temos o primeiro for
e logo criamos o nosso:
numero = geraUm();
Vamos supor que o número aleatório sorteado foi 8
, então temos o segundo for
e começa as verificações:
for(posicao=0;posicao<=sequencia.length;posicao++){
numero é igual a sequência na posição 0 ?
Não, então adicionamos o número o número 8, agora temos:
Voltamos para o for agora com posição = 1
e sequencia.length = 1
e vamos para a verificação:
numero é igual sequência na posição 1 ?
Não, então adicionamos o número 8, agora temos:
Voltamos para o for agora com posição = 2
e sequencia.length = 2
e vamos para a verificação:
numero é igual sequência na posição 2 ?
Não, então adicionamos o número 8
Bem, acredito que já entendeu o que está acontecendo, na verdade precisamos que a posição seja menor que sequencia.length
e não menor igual :)
Mas temos um outro problema:
Imagine que começamos o nosso array de sequencia da seguinte maneira e corrigimos o problema acima:
E vamos utilizar a mesma lógica:
'número é igual a posicao[0] ?
Não, 8 é diferente de 1, então insere
número é igual a posicao[1] ?
Não, 8 é diferente de 3, então insere
numero é igual a posicao[2] ?
Sim, então quebra o loop!
Isto é, inserimos duas vezes o número secreto e só paramos porque encontramos o primeiro 8 inserido pelo nosso loop, então não estamos realmente evitando números repetidos, pelo contrário, estamos vários repetidos
E a razão disso é que na verdade não temos uma relação de if- else
, na verdade temos uma condição de 2 if's, basicamente o nosso programa precisa funcionar da seguinte maneira:
- Olha percorrer todos elementos do array e veja se tem algum repetido, se existir me avisar
- Então, existe repetido?
O que você fez foi basicamente:
- Olha percorre todos elementos e se o elemento não for diferente então insere na lista
E para termos o comportamento que queremos é bem simples, precisamos criar uma variável de controle, por exemplo: var existe = false
depois do primeiro for
E deixaremos nosso for da seguinte maneira:
for(posicao=0;posicao < sequencia.length;posicao++){
if(numero == sequencia[posicao]){
existe = true;
break;
}
Ou seja percorre todos elementos e me diz se tem alguém repetido,
E após acabar esse for teremos:
if(existe == false){
sequencia.push(numero);
}
Ou seja, se existe terminou como false
então pode inserir que não é repetido
E uma última mudança que precisamos fazer:
O for sempre que termina a execução acrescenta uma unidade em calc
, então da maneira que você fez, sem loop infinito e sem inserir repetido ainda temos um problema, que é se inserimos repetido no final ele acaba fazendo o calc++
, então não vamos ter a quantidade que queremos
Para corrigir isso precisamos trocar o for
por um while
que ai temos controle de quando queremos que aumente :)
Então no final teremos algo parecido com isso:
var sequencia = [];
var contador = 0;
function geraUm() {
return Math.round(Math.random() * 10);
}
function inserirNoArray(x) {
while (contador < x) {
var existe = false;
var numero = geraUm();
for (posicao = 0; posicao < sequencia.length; posicao++) {
if (numero == sequencia[posicao]) {
existe = true;
break;
}
}
if (existe == false) {
sequencia.push(numero);
contador++;
}
}
}
inserirNoArray(5);
mostra(sequencia);
Abraços e Bons Estudos!