Ir para conteúdo
Entre para seguir isso  
Lordfire

Funções iteradoras em Lua

Recommended Posts

Lordfire    110
Lordfire

Iteradores são funções especiais criadas para iterar, ou seja, percorrer, listas, vetores (arrays), matrizes, tabelas ou o que quisermos. Nós criamos iteradores para usar na função for. Um exemplo de iterador que você já deve conhecer é o pairs. Vamos supor que eu tenha a seguinte tabela:

 

k = {1, 2, 3, 4, 5}

 

E eu queira iterar por todos eles imprimindo o seu quadrado. Como faríamos isso? Casualmente, o código seria este:

 

for i = 1, 5 do
print(i ^ 2)
end

 

Mas e se eu quiser fazer isso várias vezes? Com uma lista que não segue um padrão? Então criamos um iterador, mas primeiro, vamos entender a estrutura de um em pseudocódigo Lua:

 

function iterator(values)
local pos = 0 --posição do iterador na lista
return function()
	pos = pos + 1
	if values[pos] ~= nil then
		return values[pos]
	end
	return nil
end
end

 

Perceba que eu não retorno um valor especifico ao chamar a função iterator(), eu retorno uma nova função. Essa função será chamada pelo for até que seu retorno seja nil, onde Lua assume que o iterador acabou. E como eu sei quando acaba? Simples, há uma variável (chamei, neste caso, de pos) que armazena a posição dentro do array values do próximo valor a ser retornado. A cada iteração, o valor aumenta em 1 dentro da função. Quando eu acessar um índice dentro do array que não existe, seu valor (values[pos]) será nil, portanto eu testo essa condição.

 

Parece bastante complexo, mas vamos voltar ao exemplo do quadrado. Chamarei minha função iteradora de square:

 

function square(numbers)
local pos = 0
return function()
	pos = pos + 1
	if values[pos] ~= nil then
		return values[pos] ^ 2
	end
	return nil
end
end

 

A cada chamada da função de retorno, eu aumento a posição e retorno este elemento elevado ao quadrado. Então, usarei a função assim:

 

for i in square(k) do
print(i)
end

 

Que funciona como o esperado:

 

O que mais podemos fazer com iteradores? Podemos, por exemplo, bloquear uma palavra usando a função onTalk do xotservx (pesquise no Google):

 

local palavra = "jujuba"

function splitWords(phrase)
local pos = 0, words = phrase:gmatch("%w+")
return function()
	pos = pos + 1
	if words[pos] ~= nil then
		return words[pos]
	end
	return nil
end
end

function onTalk(cid, type, text, position)
for w in splitWords(text) do
	if w = palavra then
		return false
	end
end
return true
end

 

Claro que esse exemplo é bastante simplório, mas demonstra a utilidade dos iteradores. Neste caso, eu testo todas as palavras que o player falou para encontrar uma palavra especifica que eu defini. Podemos transformar isso tudo em um loop while, para você entender um pouco melhor:

 

local words = splitWords(text)
while w = words() do
	if w == nil then
		break
	end
	if w = palavra then
		return false
	end
end
end
return true

 

Usando o iterador, ganhamos organização no código e o controle do for. Espero que façam bom uso de iteradores para organizar seus códigos :)

Editado por Lordfire

Compartilhar este post


Link para o post
Startix    9
Startix

Aprovado e movido!

 

Obrigado pela contribuição, a OTServ Brasil agradece!

Compartilhar este post


Link para o post
Samuel1234    0
Samuel1234

A pesar de não ser util pode servir, para alguem que necessite. Mais vlw pelo post, muito bem formatado e organizado espero ver mais post seu com conteudo, embrajador e bom espero, que a otbr curta seu conteudo muito bem feito.

Compartilhar este post


Link para o post
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  
  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×