Em lua 5.1, você pode iterar os caracteres de uma string de algumas maneiras.
O loop básico seria:
para i = 1, #str faça
local c = str: sub (i, i)
- faça algo com c
fim
Mas pode ser mais eficiente usar um padrão string.gmatch()
para obter um iterador sobre os caracteres:
para c em str: gmatch "." Faz
- faça algo com c
fim
Ou ainda para usar string.gsub()
para chamar uma função para cada char:
str: gsub (".", função (c)
- faça algo com c
fim)
Em todos os itens acima, aproveitei o fato de que o string
módulo é definido como uma metatabela para todos os valores de string, portanto, suas funções podem ser chamadas como membros usando a :
notação. Eu também usei o (novo no 5.1, IIRC) #
para obter o comprimento da string.
A melhor resposta para sua aplicação depende de muitos fatores, e os benchmarks são seus amigos se o desempenho for importante.
Você pode querer avaliar por que precisa iterar sobre os caracteres e olhar para um dos módulos de expressão regular que foram vinculados a Lua, ou para uma abordagem moderna, dê uma olhada no módulo lpeg de Roberto que implementa Parsing Expression Grammers para Lua.
Se você estiver usando Lua 5, tente:
fonte
Dependendo da tarefa em mãos, pode ser mais fácil de usar
string.byte
. É também a maneira mais rápida porque evita a criação de uma nova substring que parece ser muito cara em Lua graças ao hash de cada nova string e à verificação se ela já é conhecida. Você pode pré-calcular o código de símbolos que procura parastring.byte
manter a legibilidade e a portabilidade.fonte
Já existem muitas boas abordagens nas respostas fornecidas ( aqui , aqui e aqui ). Se velocidade é o que você está procurando principalmente , definitivamente deve considerar fazer o trabalho por meio da API C de Lua, que é muitas vezes mais rápida do que o código Lua bruto. Ao trabalhar com blocos pré-carregados (por exemplo, função de carregamento ), a diferença não é tão grande, mas ainda é considerável.
Quanto às soluções Lua pura , deixe-me compartilhar este pequeno benchmark que fiz. Ele cobre todas as respostas fornecidas até esta data e adiciona algumas otimizações. Ainda assim, o básico a considerar é:
Quantas vezes você precisará iterar sobre os caracteres da string?
Aqui está o código completo:
Saída de exemplo (Lua 5.3.4, Windows) :
Resultado:
No meu caso, os
string.byte
estring.sub
foram os mais rápidos em termos de velocidade bruta. Ao usar a tabela de cache e reutilizá-la 10 vezes por loop, astring.byte
versão foi mais rápida mesmo ao converter charcodes de volta para chars (o que nem sempre é necessário e depende do uso).Como você provavelmente notou, fiz algumas suposições com base em meus benchmarks anteriores e as apliquei ao código:
tbl[idx] = value
quetable.insert(tbl, value)
.for i = 1, #tbl
é um pouco mais rápido do quefor k, v in pairs(tbl)
.Espero que ajude.
fonte
Todas as pessoas sugerem um método menos ideal
Será o melhor:
fonte