Pergunta

Se eu tenho uma lista de itens como este:

local items = { "apple", "orange", "pear", "banana" }

Como posso verificar se "laranja" está nesta lista?

Em Python eu poderia fazer:

if "orange" in items:
    # do something

Existe um equivalente em Lua?

Foi útil?

Solução

Você pode usar algo como um conjunto de em Lua :

function Set (list)
  local set = {}
  for _, l in ipairs(list) do set[l] = true end
  return set
end

Em seguida, você pode colocar sua lista no jogo e teste para a adesão:

local items = Set { "apple", "orange", "pear", "banana" }

if items["orange"] then
  -- do something
end

Ou você pode iterar sobre a lista diretamente:

local items = { "apple", "orange", "pear", "banana" }

for _,v in pairs(items) do
  if v == "orange" then
    -- do something
    break
  end
end

Outras dicas

Use a seguinte representação em vez disso:

local items = { apple=true, orange=true, pear=true, banana=true }
if items.apple then
    ...
end

Você está vendo em primeira mão um dos contras da Lua ter apenas uma estrutura de dados --- você tem que rolar o seu próprio. Se você ficar com Lua você irá gradualmente acumular uma biblioteca de funções que manipulam as tabelas da maneira que você gosta de fazer as coisas. Minha biblioteca inclui uma conversão lista-to-set e uma função de lista à procura de ordem superior:

function table.set(t) -- set of list
  local u = { }
  for _, v in ipairs(t) do u[v] = true end
  return u
end

function table.find(f, l) -- find element v of l satisfying f(v)
  for _, v in ipairs(l) do
    if f(v) then
      return v
    end
  end
  return nil
end

tabelas Lua são mais estreitamente análogos de dicionários Python em vez de listas. A tabela que você tem criar é essencialmente uma matriz indexada com base em 1 de cordas. Usar qualquer algoritmo de busca padrão para descobrir se um valor está na matriz. Outra abordagem seria para armazenar os valores como chaves de tabela em vez como mostrado na implementação conjunto de post de Jon Ericson.

function valid(data, array)
 local valid = {}
 for i = 1, #array do
  valid[array[i]] = true
 end
 if valid[data] then
  return false
 else
  return true
 end
end

Aqui está a função que eu uso para verificar se os dados estão em uma matriz.

tipo de solução usando metatable ...

local function preparetable(t)
 setmetatable(t,{__newindex=function(self,k,v) rawset(self,v,true) end})
end

local workingtable={}
preparetable(workingtable)
table.insert(workingtable,123)
table.insert(workingtable,456)

if workingtable[456] then
...
end

Esta é uma função swiss-armyknife você pode usar:

function table.find(t, val, recursive, metatables, keys, returnBool)
    if (type(t) ~= "table") then
        return nil
    end

    local checked = {}
    local _findInTable
    local _checkValue
    _checkValue = function(v)
        if (not checked[v]) then
            if (v == val) then
                return v
            end
            if (recursive and type(v) == "table") then
                local r = _findInTable(v)
                if (r ~= nil) then
                    return r
                end
            end
            if (metatables) then
                local r = _checkValue(getmetatable(v))
                if (r ~= nil) then
                    return r
                end
            end
            checked[v] = true
        end
        return nil
    end
    _findInTable = function(t)
        for k,v in pairs(t) do
            local r = _checkValue(t, v)
            if (r ~= nil) then
                return r
            end
            if (keys) then
                r = _checkValue(t, k)
                if (r ~= nil) then
                    return r
                end
            end
        end
        return nil
    end

    local r = _findInTable(t)
    if (returnBool) then
        return r ~= nil
    end
    return r
end

Você pode usá-lo para verificar se existe um valor:

local myFruit = "apple"
if (table.find({"apple", "pear", "berry"}, myFruit)) then
    print(table.find({"apple", "pear", "berry"}, myFruit)) -- 1

Você pode usá-lo para encontrar a chave:

local fruits = {
    apple = {color="red"},
    pear = {color="green"},
}
local myFruit = fruits.apple
local fruitName = table.find(fruits, myFruit)
print(fruitName) -- "apple"

Espero que o parâmetro recursive fala por si.

O parâmetro metatables permite pesquisar metatables também.

O parâmetro keys faz o olhar de função para chaves na lista. É claro que seria inútil na Lua (você pode apenas fazer fruits[key]), mas em conjunto com recursive e metatables, torna-se acessível.

O parâmetro returnBool é um salvo-guarda para quando você tem tabelas que têm false como uma chave em uma tabela (Sim, isso é possível: fruits = {false="apple"})

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top