在Lua中,您如何找到存储对象的密钥?

时间:2012-03-17 22:19:29

标签: object lua corona lua-table

你如何打印()或找出对象的索引?

例如,如果我在屏幕上将20个随机摇滚对象衍生为数组RockTable = {};

喜欢这个RockTable[#RockTable + 1] = rock;

屏幕上会显示所有20个岩石,如何通过点击它们找出每块岩石的关键字或索引?

我正在使用Corona SDK。

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:4)

反转表:

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

然后,您可以使用倒置表来查找索引。

我发现这个函数非常有用,它可以进入我的永久“Lua实用程序”库。

答案 1 :(得分:2)

使用metamethods还有另一种方法可以做到这一点。 [已编辑,允许您删除值]

t = {} -- Create your table, can be called anything
t.r_index = {} -- Holds the number value, i.e. t[1] = 'Foo'
t.r_table = {} -- Holds the string value, i.e. t['Foo'] = 1

mt = {} -- Create the metatable
mt.__newindex = function (self, key, value) -- For creating the new indexes
    if value == nil then -- If you're trying to delete an entry then
        if tonumber(key) then -- Check if you are giving a numerical index
            local i_value = self.r_index[key] -- get the corrosponding string index
            self.r_index[key] = nil -- Delete
            self.r_table[i_value] = nil
        else -- Otherwise do the same as above, but for a given string index
            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) -- For t[1] = 'Foo'
        self.r_table[value] = key -- For t['Foo'] = 1
    end
end
mt.__index = function (self, key) -- Gives you the values back when you index them
    if tonumber(key) then
        return (self.r_index[key]) -- For For t[1] = 'Foo'
    else
        return (self.r_table[key]) -- For t['Foo'] = 1
    end
end

setmetatable(t, mt) -- Creates the metatable

t[1] = "Rock1" -- Set the values
t[2] = "Rock2"

print(t[1], t[2]) -- And *should* proove that it works
print(t['Rock1'], t['Rock2'])

t[1] = nil
print(t[1], t[2]) -- And *should* proove that it works
print(t['Rock1'], t['Rock2'])

它更通用,因为您可以复制t值并随身携带;它也意味着你只需要在大多数时间内使用一个变量 - 希望能减少你试图访问错误的可能性。

答案 2 :(得分:2)

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

RockTable = {}

for i=1,20 do

    local rock
    -- do your thing that generates a new 'rock' object

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

end

如果您使用触控侦听器方法,则可以通过以下方式检索摇滚:

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

确实可以维护带索引的第二个表,但我发现我的方法更清晰 - 当需要删除时,你只需要担心一个表,即主表。

我有一个问题:为什么你需要检索那个索引?在大多数情况下,精心设计的事件监听器功能就足够了,您不需要“找到”您的对象。当然,我缺乏关于你想要做什么的信息,但你可能会过度复杂化。

答案 3 :(得分:1)

你可以做这样的事情来节省你不断循环查找索引的麻烦......

RockTable = {}
RockIndicies = {}

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

然后当你需要知道索引时,你可以使用你所拥有的摇滚索引RockIndices来快速获得它。如果你'删除'摇滚乐,你需要确保在两个地方删除它。

答案 4 :(得分:0)

不幸的是,据我所知,你需要粗暴地对待桌子。虽然,要知道一个被点击了,你不需要以某种方式循环它们;因此已经知道指数?

修改

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

你可以做一个向后的参考,如下:

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

然后就说rockNum = RocksB [摇滚]

我很确定应该可行,但我无法保证,值得一试。

EDIT2

粗暴的方法看起来有点像:

function getRock(rock)
    for _,v in pairs(rocks) do
        if (v == rock)
            return _
        end
    end
    return "Rock does not exist."
end