在Lua中,你如何找出一个对象存储在哪个键中?

如何使用print()输出或查找对象的索引?

例如,如果我在屏幕上生成了20个随机的rock对象,并将它们存储在一个名为RockTable的数组中:

RockTable = {};

RockTable[#RockTable + 1] = rock;

当这20个石头都显示在屏幕上时,我如何通过点击它们来找出每个石头有哪个索引或键?

我使用的是Corona SDK。

任何帮助都将不胜感激。

原文链接 https://stackoverflow.com/questions/9754285

点赞
stackoverflow用户511258
stackoverflow用户511258

不幸的是,据我所知,你需要暴力搜索表格才能解决这个问题。不过,要知道哪一个被点击了,你不是必须以某种方式循环它们吗?因此,你已经知道了索引?

编辑

哦,除非 Corona 有某种回调事件来处理点击。我从未使用过它,但我有 Lua 经验。

你可以尝试反向引用,像这样:

Rocks = {a rock, a rockB, a rockC}
RocksB = {[a rock] = 1, [a rockB] = 2, [a rockC] = 3}

然后只需说 rockNum = RocksB[rock]

我非常确定这应该可以运行,但我不能保证,不过还是值得一试的。

编辑2

暴力方法看起来应该像这样:

function getRock(rock)
    for _,v in pairs(rocks) do
        if (v == rock)
            return _
        end
    end
    return "Rock does not exist."
end
2012-03-17 22:29:43
stackoverflow用户1208078
stackoverflow用户1208078

你可以像这样做来避免频繁循环遍历表格来查找索引...

RockTable = {}
RockIndicies = {}

for i = 1, 20 do
    idx = #RockTable + 1
    RockTable[idx] = rock
    RockIndicies[rock] = idx
end

然后当你需要知道索引时,你只需使用你所拥有的岩石来索引RockIndices,以快速获取它。如果你“删除”了一块岩石,你需要确保在两个地方都将其删除。

2012-03-17 23:57:18
stackoverflow用户41661
stackoverflow用户41661

反转表格:

function table_invert(t)
  local u = { }
  for k, v in pairs(t) do u[v] = k end
  return u
end

你可以使用反转后的表格来查找索引。

我发现这个函数非常有用,所以将其放入了我永久的 "Lua utilities" 库中。

2012-03-19 02:56:09
stackoverflow用户319344
stackoverflow用户319344

还有另一种方法可以实现它,使用元方法。

[编辑允许您删除值]

t = {} -- 创建表,可以任意命名
t.r_index = {} -- 保存数值,例如 t[1] = 'Foo'
t.r_table = {} -- 保存字符串,例如 t['Foo'] = 1

mt = {} -- 创建元表
mt.__newindex = function (self, key, value) -- 用于创建新索引
    if value == nil then -- 如果您要删除一个条目,则
        if tonumber(key) then -- 检查是否给出了数字索引
            local i_value = self.r_index[key] -- 获取相应的字符串索引
            self.r_index[key] = nil -- 删除
            self.r_table[i_value] = nil
        else -- 否则执行上述相同的操作,但是针对特定的字符串索引
            local t_value = self.r_table[key]
            self.r_index[t_value] = nil
            self.r_table[key] = nil
        end
    else
        table.insert(self.r_index, tonumber(key), value) -- 对于 t[1] = 'Foo'
        self.r_table[value] = key -- 对于 t['Foo'] = 1
    end
end
mt.__index = function (self, key) -- 当您索引它们时,返回值
    if tonumber(key) then
        return (self.r_index[key]) -- 对于 t[1] = 'Foo'
    else
        return (self.r_table[key]) -- 对于 t['Foo'] = 1
    end
end

setmetatable(t, mt) -- 创建元表

t[1] = "Rock1" -- 设置值
t[2] = "Rock2"

print(t[1], t[2]) -- 应该证明它起作用了
print(t['Rock1'], t['Rock2'])

t[1] = nil
print(t[1], t[2]) -- 应该证明它起作用了
print(t['Rock1'], t['Rock2'])

它更加灵活,因为您可以复制t的值并将其带走;这也意味着您大部分时间只需要操作一个变量 - 希望可以减少访问错误的可能性。

2012-03-19 18:11:26
stackoverflow用户1286247
stackoverflow用户1286247

最简单的方法是为每个岩石添加一个“索引”属性:

RockTable = {}

for i=1,20 do

    local rock
    -- 实现生成新“岩石”对象的代码

    rock.index = #RockTable + 1
    RockTable[rock.index] = rock

end

如果你使用触摸监听器方法,可以通过以下方式检索到岩石:

function touchListener( event )
    local rock = event.target
    local rockIndex = rock.index
    -- ...
end

尽管你可以维护一个具有索引的二级表,但我认为我的方法更加简洁 - 当需要移除物体时,你只需要关注主表格。

不过我有一个问题:你为什么需要检索该索引?在大多数情况下,设计良好的事件监听器函数已经足够,你不需要“找”对象。当然,我缺乏你尝试做什么的信息,但你可能是在过度复杂化问题。

2012-03-22 15:30:41