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.

+3


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
end

      



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.

+4


source


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

      



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.

+2


source


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

end

      

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

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

      

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.

+2


source


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
end

      

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.

+1


source


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?

Edit

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.

Edit2

The hard method would look something like this:

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

      

0


source







All Articles