length - Busque un artículo en una lista de Lua
push array lua (7)
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?
Está viendo de primera mano que uno de los contras de Lua tiene una sola estructura de datos, tiene que hacer la suya propia. Si te apegas a Lua, acumularás gradualmente una biblioteca de funciones que manipulan las tablas de la manera en que te gusta hacer las cosas. Mi biblioteca incluye una conversión de lista a configurar 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
Esta es una función swiss-armyknife 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
Puedes 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 recursive
hable por sí mismo.
El parámetro metatables
permite buscar metatablas.
El parámetro keys
hace que la función busque claves en la lista. Por supuesto, eso sería inútil en Lua (puedes simplemente hacer las fruits[key]
) pero junto con recursive
metatables
y los recursive
, resulta útil.
El parámetro returnBool
es una protección segura cuando tienes tablas que tienen una clave false
en una tabla (sí, eso es posible: fruits = {false="apple"}
)
Las tablas de Lua son análogos más cercanos de los diccionarios de Python que de las listas. La tabla que tiene crear 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 en su lugar, como se muestra en la implementación del conjunto de la publicación de Jon Ericson.
Puede usar algo así 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
Luego puede 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 puede 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
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
Use la siguiente representación en su lugar:
local items = { apple=true, orange=true, pear=true, banana=true }
if items.apple then
...
end
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.