Corona SDK (LUA) - Trouble With Inserting Into Table - lua

I have searched around quite a bit and couldn't quite find a solution for this. Any help you can offer would be appreciated.
-- The array compiled of enemies only allowed in the current
-- level phase
local EnemyList = {}
-- Counter to determine the next spot in the EnemyList
-- array to insert into
local counter = 1
for i=1,#Enemies do
if Enemies[i].phase == 0 or Enemies[i].phase == which_phase then
EnemyList[counter].src = Enemies[i].src
EnemyList[counter].exp = Enemies[i].exp
counter = counter + 1
end
end
I am getting an error about attempting to index a nil value, in reference to the EnemyList table/array. What I am trying to accomplish is I am trying to compile a new array of only enemies that are allowed. I guess I am unsure how to insert a new row into the EnemyList table. I tried using table.insert, but the value parameter is required, and I am not sure how to do that with the fact that I am storing multiple values into the EnemyList array.
Any help or insight on the proper way to insert a new row into an empty table/array would be much appreciated. Thanks!
EDIT:
I got a working solution, but I figured I should update the code here if anyone in the future finds it.
-- The array compiled of enemies only allowed in the current
-- level phase
local EnemyList = {}
for i=1,#Enemies do
if Enemies[i].phase == 0 or Enemies[i].phase == which_phase then
table.insert( EnemyList, { src = Enemies[i].src, exp = Enemies[i].exp } )
end
end

You can store tables within tables in Lua. Tables are indexed in one of two ways: First, by index number. This is what table.insert uses; it will add an entry at the next index number.
The second way is by key; e.g.
> t = {}
> t.test = {}
> =t.test
table: 0077D320
You can insert tables into tables; this is how you create a 2D table. Because of the way you've defined your tables, type(EnemyList[counter]) = table.
You can insert new entries into tables by running table.insert(table, value). This will assign value to the next available numeric entry. type(value) can also be a table; this is how you create "multidimensional arrays" in Lua.
As an aside, instead of using for i=1,#Enemies I would suggest using for i,v in ipairs(Enemies). The second one will iterate over all numerical entries in the Enemies table.

Related

lua Adding key value pair in nested table

Im new to lua and have a problem which i believe has an elegant solution, but i just cant make it work. I've read similar questions and answers here on stack overflow and elsewhere for hours as well as testing in online lua compiler but no real progress.
Q:
i start out with an empty table:
local vertices = {}
Now, with a for loop or similar i want to populate this table so the end result has this form:
local vertices = {
{x=-6.0, y=0.0},
{x=0.0, y=1},
}
Where the values in the entries {x=-6.0, y=0.0} are arbitrary, and the number of these {x=0.0, y=1} (coordinates) are also arbitrary.
These values are to be fetched from another table and som calculated in the for loop, but that is the next step. For now i just need help populate my empty table with x,y values in a loop.
Thanks to you all.
You can add elements to a Lua table through
the table constructor local t = { v1, v2, v3 }
assignment t[k1] = v1 t[k2] = v2
table.insert(t, 1) (for consecutive integer indices starting at 1)
rawset(t, 1, 1) if you want to avoid invoking metamethods
table.move to copy elements fro one to another table
...
For your case you can simply use assignment in a for loop.
local vertices = {}
for i = 1, 100 do
vertices[i] = NewVertex();
end
To add 100 vertices to the table.

How to reference an object in a table in Lua by its name

This seems like a very straightforward question, but I haven't been able to turn up an answer. I am adding game objects to a table in Lua like this:
local lock = GameObject {
-- object values and methods
table.insert(objects, lock)
But despite a lot of google searching and reading through the Lua documentation, I cannot figure out how to reference these objects by their names. I think it's because there is a very specific syntax to do so. If anyone could help me out, I would greatly appreciate it. Thanks!
You might want to do something like this instead of table.insert. Objects will still be a table.
objects = {}
objects.lock = {}
objects.lock2 = {}
If you then execute
for key, value in pairs(objects) do
print(key,value)
end
You will get the output
lock2 table: 0x1af3310
lock table: 0x1af3870
Further explanation
In you question(not the solution above) lock is only the variable name given to it, it is not the name of the index.
In this code snippet, you can see that the items being inserted into objects do not have the variable name recorded within objects. objects is storing an int as the key, and then the inserted table as the value.
objects = {}
local lock = {}
local lock2 = {}
-- object values and methods
table.insert(objects, lock)
table.insert(objects, lock2)
for key, value in pairs(objects) do
print(key,value)
print(type(value))
end
prints
1 table: 0x131b590
table
2 table: 0x131b540
table
test it on repl

Potential problems with storing the second table of two dimensional arrays in the index

In the past I found myself using a table as index and value of
a table when the order was irrelevant.
Since every table returns a unique value they are save to use as
index and with that I already got all the information I want to
use later on in the program. Now I did not see any similar lua code
jet and didn't use it in a non test-program. So I'm worrying that I
might get some unforeseen/unexpected problems when using this method.
example:
a = {1,2,3,4,5} --some testing values
b = {2,nil,4,nil,1}
c = {3,nil,nil,nil,2}
d = {4,nil,1,nil,3}
e = {5,1,2,3,4}
tab = {a,b,c,d,e}
t = {}
for i, v in pairs(tab) do
t[v] = 0
end
for iv in pairs(t) do --is almost every time outputting it in a different order
print(iv[1],iv[2],iv[3],iv[4],iv[5]) --could be a list of data where you have to go through all of it anyway
end
io.read()
Now I can store some additional information in t[v] but if I don't have
any is there maybe some lua-type that is smaller?
Edit:
Does this go well with the use of weak-tables?
Note:
Standard 2d table: table[key1] = table
table[key1][key2] <-- contains stuff
this version: table[table] = anything but nil <-- not accessible over table[key1][key2]
key1[key2] <-- contains stuff
It's fine to use a table as a key in another table.
However, note that different tables will be different keys, even of the tables have the same contents.

Lua deleting an item from table (CoronaSDK)

Been trying to work this out for hours and not getting anywhere despite lots of searching, so if somebody can help that would be great
My issue is I have a table of objects which are added like this
enemies[enemy_id] = enemy
Now when there is a collision at the end of the map I want to remove that enemy from the table. I have tried removing by
enemies[enemy_id] = nil
But when it gets to the last enemy the table is already empty for some reason. Say there's 3 enemies in a table, I print the count of the table. The first one is removed it shows 2 left, 2nd is removed it shows 0 left. Doesn't make sense
So how do you remove an item from a table? I have also tried table.remove but I need to key the same keys because they are the id of the enemy. I can post an example if need be
When working with "sparse keys" in Lua tables this pattern usually pays off for me:
-- add item to registry
registry[object] = key
registry[key] = object
-- iterate over all items in registry
for k,v in pairs(registry) do
if type(k) == "number" then do_something(k,v) end
end
-- remove item with key K from registry:
registry[registry[K]] = nil
registry[K] = nil
-- remove item O from registry:
registry[registry[O]] = nil
registry[O] = nil
Since # won't work on sparse arrays, as other suggested, and my solution would be to use 0 index (or simply another variable) as count:
enemies[0] = 0
Then, when you add an enemy, increase the counter, when you remove one, decrease it. Simple as that.

How can I compress a table after having removed a value from it?

I have a table which contains 4 values.
For example:
2
4
1
3
I use a function to step through the table looking for, lets say the number 1 by using pairs and to get the position of it in the table.
I then use table.remove to remove 1 from that position. What I would like to do now is to compress the table so that it is 3 values long
2
4
3
I'm fairly new to LUA so be gentle with me. :)
What I have is pretty much this:
CloseRandomConsole = math.random(1,(#ConsoleTable))
If CloseRandomConsole == 1 then
for key, value in pairs(ConsoleTable) do
if value == "1" then
table.remove(ConsoleTable, key)
break
end
end
I see where I'm going wrong but I hae no idea how to solve it.
math.random(1,(#ConsoleTable))
I only want to be able to random between one of the values in the table. And when I have randomed that vlue I want it removed so that I will be left with three other values to random from.
Am I confusing you? :)
What do you mean?
s = {2,4,1,3} -- the table
for k,v in pairs(s) do
if v==1 then
table.remove(s,k)
end
end
print(#s) -- is now 3
for k,v in pairs(s) do print(v) end -- just the 3 values ...
#Vitae: When you're asking about anything, you should describe what you want to do, not how you want to do it -- especially when you have no idea what you're doing ...
Maybe you want to remove a random value from the table? Then fetch the value at a random index ...
function poprandom( t )
local idx = math.random(1,#t)
local ret = t[idx]
table.remove(t, idx)
return ret
end

Resources