Pregunta

Si tengo una lista de elementos como este:

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

¿Cómo verifico si " naranja " está en esta lista?

En Python podría hacer:

if "orange" in items:
    # do something

¿Hay un equivalente en Lua?

¿Fue útil?

Solución

Podría usar algo como un conjunto de Programación en Lua :

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

Entonces podría poner su lista en el Conjunto y probar la membresía:

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

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

O podría iterar sobre la lista directamente:

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

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

Otros consejos

Utilice la siguiente representación en su lugar:

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

Estás viendo de primera mano una de las desventajas de que Lua tiene una sola estructura de datos: tienes que rodar la tuya. Si te quedas con Lua, acumularás gradualmente una biblioteca de funciones que manipulan las tablas de la forma en que te gusta hacer las cosas. Mi biblioteca incluye una conversión de lista a conjunto y una función de búsqueda de lista de orden 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

Las tablas Lua son más análogas a los diccionarios de Python que a las listas. La tabla que ha creado es esencialmente una matriz indexada de cadenas basada en 1. Use cualquier algoritmo de búsqueda estándar para averiguar si hay un valor en la matriz. Otro enfoque sería almacenar los valores como claves de tabla, como se muestra en la implementación establecida de la publicación 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

Aquí está la función que uso para verificar si los datos están en una matriz.

Tipo de solución usando metatabla ...

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 es una función navaja suiza que puedes 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

Puede usarlo para verificar si existe un valor:

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

Puede usarlo para encontrar la clave:

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

Espero que el parámetro recursivo hable por sí mismo.

El parámetro metatables también le permite buscar metatables.

El parámetro keys hace que la función busque teclas en la lista. Por supuesto, eso sería inútil en Lua (puede hacer fruits [key] ) pero junto con recursive y metatables , se vuelve útil.

El parámetro returnBool es una protección para cuando tiene tablas que tienen false como clave en una tabla (Sí, eso es posible: fruits = { false = " manzana "} )

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top