Lua:É possível diminuir o iterador de dentro do loop?
Pergunta
array={}
size=10
math.randomseed(os.time())
for i=1,size do
array[i]=math.random(size)
if(i>1) then
for j=1,i do
if array[j]==array[i] then
i=i-1
break
end
end
end
end
for i=1,size do
print(array[i])
end
O código acima foi criado para gerar um array de números aleatórios de 1 a 'tamanho' evitando a repetição de valores.Tentei conseguir isso repetindo o loop 'for' de nível superior mais uma vez se o valor recém-gerado estivesse presente antes em algum lugar da matriz - diminuindo seu iterador.De alguma forma isso não funciona.Por que?
Não é possível modificar o valor do iterador de dentro do loop?
Exemplo de saída com valores repetidos na matriz:
>lua5.1 "pairsss.lua"
2
1
10
6
5
2
5
7
7
4
>Exit code: 0
Solução
A solução para o seu problema é embaralhar o array, como Iteração aleatória para preencher uma tabela em Lua.
Para responder à sua pergunta, de Manual de referência Lua 5.1:
§2.4.5 – Para Declaração
Todas as três expressões de controle são avaliadas apenas uma vez, antes do início do loop.Todos eles devem resultar em números.
Isso significa que não importa como você altera o valor de i
dentro de for
loop, isso não afeta como a iteração é feita.
Outras dicas
Você pode usar um conjunto em vez de um array, como feito pelo autor da pergunta Randomize números em Lua sem repetições.Como uma das respostas aponta, à medida que o tamanho do seu conjunto se aproxima do seu intervalo de números aleatórios (digamos, você tem números aleatórios de 1 a 100 e seu conjunto tem tamanho 50), será cada vez mais difícil encontrar um número que ainda não foi escolhido.Você pode ver que, para um conjunto de tamanho 50 e escolhendo um número aleatório de 1 a 100, quando tiver o conjunto meio cheio, você terá 25-50% de chance de descobrir que a escolha aleatória já está em uso em seu definir.Nesse caso, embaralhar é o caminho a seguir, conforme explicado em uma das respostas a esse post (Randomize números em Lua sem repetições).