如何搜索Lua表值

时间:2014-11-14 21:29:33

标签: search lua lua-table

我有一个项目,在不可能实际数据库的环境中调用关系数据库,如结构。这种语言仅限于Lua,这远非我最强的语言。我有一张表格,表格结构如下:

table={
  m:r={
    x=1
    y=1
    displayName="Red"
  }
  m:y={
    x=1
    y=2
    displayName="Yellow"
  }
}

构建,存储和检索表格非常简单。我遇到问题的地方就是搜索它。为了清楚起见,如果我可以使用SQL,我会这样做:

SELECT * FROM table WHERE displayName="Red"

是否有Lua功能可让我以这种方式搜索?

2 个答案:

答案 0 :(得分:2)

直截了当的方法是遍历所有元素并找到符合条件的元素:

local t={
  r={
    x=1,
    y=1,
    displayName="Red",
  },
  y={
    x=1,
    y=2,
    displayName="Yellow",
  },
}
for key, value in pairs(t) do
  if value.displayName == 'Red' then
    print(key)
  end
end

这应该打印'r'。

在大型桌子上这可能会非常慢。为了加快此过程,您可以跟踪hash中将提供更快访问的参考。这样的事情可能有用:

local cache = {}

local function findValue(key)
  if cache[key] == nil then
    local value
    -- do a linear search iterating through table elements searching for 'key'
    -- store the result if found
    cache[key] = value
  end
  return cache[key]
end

如果表中的元素更改了它们的值,则在更新或删除值时,您需要使缓存无效。

答案 1 :(得分:0)

没有用于搜索表格的内置函数。有很多方法可以解决它的复杂性和效率。

local t = {
  r={displayname="Red", name="Ruby", age=15, x=4, y=10},
  y={displayname="Blue", name="Trey", age=22, x=3, y=2},
  t={displayname="Red", name="Jack", age=20, x=2, y=3},
  h={displayname="Red", name="Tim", age=25, x=2, y=33},
  v={displayname="Blue", name="Bonny", age=10, x=2, y=0}
}

Programming in Lua中,他们建议构建一个反向表,以便有效地查找。

 revDisplayName = {}
 for k,v in pairs(t) do
      if revDisplayName[v.displayname] then
          table.insert(revDisplayName[v.displayname], k)
      else
         revDisplayName[v] = {k}
      end
 end 

然后您可以轻松匹配显示名称

for _, rowname in pairs(revDisplayName["Red"]) do
   print(t[rowname].x, t[rowname].y)
end

如果你想构建复杂的查询,可以在Lua表中的Beginning Lua Programming中创建类似SQL的查询代码。

如果您只想搜索一些匹配的记录,可以使用iterator in Lua

抽象搜索
function allmatching(tbl, kvs)
  return function(t, key)
    repeat
      key, row = next(t, key)
      if key == nil then
        return
      end
      for k, v in pairs(kvs) do
        if row[k] ~= v then
          row = nil
          break
        end
      end
    until row ~= nil
    return key, row
  end, tbl, nil
end

你可以这样使用:

for k, row in allmatching(t, {displayname="Red", x=2}) do
  print(k, row.name, row.x, row.y)
end

打印

h   Tim     2   33
t   Jack    2   3