In Lua, how do you know the key that holds an object?

How can you print () or find out the index of an object?

For example, if I spawned 20 random objects on the screen into an array RockTable = {};

Like this RockTable[#RockTable + 1] = rock;

And all 20 stones are displayed on the screen, how would I know which key or index of each rock by clicking on them?

I am using Corona SDK.

Any help would be greatly appreciated.


source to share

5 answers

Invert table:

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


Then you can use the inverted table to find the index.

I find this feature so useful that it is included in my Lua utilities persistent libraries.



There you can do it using metamethods. [Edited so you can delete values ​​as well]

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
        table.insert(self.r_index, tonumber(key), value) -- For t[1] = 'Foo'
        self.r_table[value] = key -- For t['Foo'] = 1
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'
        return (self.r_table[key]) -- For t['Foo'] = 1

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'])


This is more versatile because you can copy the value t

and take it with you; it also means that you only need to play with one variable most of the time - hopefully this should reduce the likelihood that you are trying to access the wrong thing.



The easiest way is to add an "index" property for each rock:

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



If you are using the touch listener method you can get the rock this way:

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


It is true that you can keep a second table with indexes, but I find my method cleaner - when it's time to delete things, you only need to worry about one table, the main one.

I have a question: why do you need this index? In most cases, with well-designed event listeners, you don't need to "find" your objects. Of course, I am missing information on what you are trying to do, but it is possible that you are over complicating the situation.



you could do something like this to save you any trouble with traversing the table constantly to find the index ...

RockTable = {}
RockIndicies = {}

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


then when you need to know the index you can just use the rock you have to index RockIndices to get it quickly. If you remove the stone, you must make sure to remove it in both places.



Unfortunately, you will need to copy the table as far as I know. Although, to know that one clicked, you didn't have to loop them anyway; and therefore already know the index?


Oh, if Corona doesn't have some sort of callback event to push. I've never used it, but I have some experience with Lua.

Maybe you can do a backlink like:

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


Then just say rockNum = RocksB [rock]

I'm sure I'm working, but I can't guarantee it, it's worth a try.


The hard method would look something like this:

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




All Articles