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
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.
source to share
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.
source to share
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.
source to share
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
source to share