Existe um método para verificar se uma tabela contém um valor? Tenho minha própria função (ingênua), mas gostaria de saber se existe algo "oficial" para isso? Ou algo mais eficiente ...
function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
A propósito, o principal motivo pelo qual estou usando essas funções é usar tabelas como conjuntos, ou seja, sem elementos duplicados. Existe algo mais que eu possa usar?
_
.pairs()
retornakey, value
, mas neste exemplo eu só preciso do valor. É uma espécie de convenção (adotada no livro "Programação em Lua" lua.org/pil/index.html ) usar esta_
variável para armazenar coisas que você não precisa._
usadas em Python e JavaScript também.Respostas:
Você pode colocar os valores como as chaves da tabela. Por exemplo:
Há um exemplo mais completo aqui .
fonte
function keysOfSet(set) local ret={} for k,_ in pairs(set) do ret[#ret+1]=k end return ret end
Dada a sua representação, sua função é tão eficiente quanto pode ser feita. É claro que, conforme observado por outros (e praticado em linguagens anteriores a Lua), a solução para seu problema real é mudar a representação. Quando você tem tabelas e deseja conjuntos, transforma as tabelas em conjuntos usando o elemento set como chave e
true
como valor. +1 para interjay.fonte
Não consigo pensar em outra maneira de comparar valores, mas se você usar o elemento do conjunto como a chave, poderá definir o valor para qualquer coisa diferente de nulo. Assim, você obtém pesquisas rápidas sem ter que pesquisar toda a tabela.
fonte
Eu sei que este é um post antigo, mas queria acrescentar algo para a posteridade. A maneira simples de lidar com o problema que você tem é fazer outra tabela, de valor para chave.
ie. você tem 2 tabelas com o mesmo valor, uma apontando para uma direção e uma apontando para a outra.
Você pode então consultar a nova tabela para ver se ela contém o 'elemento' chave. Isso evita a necessidade de iterar por todos os valores da outra tabela.
Se descobrir que você não pode realmente usar o 'elemento' como uma chave, porque não é uma string, por exemplo, adicione uma soma de verificação ou
tostring
nela, por exemplo, e use-a como a chave.Por que você quer fazer isso? Se suas tabelas forem muito grandes, a quantidade de tempo para iterar em cada elemento será significativa, impedindo que você faça isso com muita frequência. A sobrecarga de memória adicional será relativamente pequena, pois armazenará 2 ponteiros para o mesmo objeto, em vez de 2 cópias do mesmo objeto. Se suas tabelas forem muito pequenas, isso importará muito menos; na verdade, pode ser até mais rápido iterar do que ter outra pesquisa de mapa.
A formulação da pergunta, entretanto, sugere fortemente que você tem um grande número de itens para tratar.
fonte