how to dynamically name element in a lua table - lua

I have the following test code:
local luatable = {}
luatable.item1 = 'abc'
luatable.item2 = 'def'
I'd like to know how to change it so that I can dynamically assign the names becuase I don't know how many "items" I have. I'd like to do something like this:
(pseudo code)
n = #someothertable
local luatable = {}
for i = 1, n do
luatable.item..i = some value...
end
Is there a way to do this?

I'd like to do something like this: luatable.item..i = value
That would be
luatable['item'..i] = value
Because table.name is a special case shorthand for the more general indexing syntax table['name'].
However, you should be aware that Lua table indexes can be of any type, including numbers, so in your situation you most likely just want:
luatable[i] = value

Yes, and the correct code is
for i = 1, n do
luatable["item"..i] = some value...
end
Recall that luatable.item1 is just sugar for luatable["item1"].

Related

Obtain values from embedded tables Lua

I am new to Lua and I am trying to learn how to make a function with embedded tables. I am stuck trying to figure out a way to make the function meet specific values in the table.
Here is an example of a table:
TestTable = {destGUID1 = {catagory1 = {A=1,B=5,C=3},catagory2 = {A=5,B=3,C=2}},destGUID2 = {catagory1 = {A=1,B=5,C=3},catagory2 = {A=5,B=3,C=2}}}
Now I want to make a function for this table that pulls values only from the specific destGUID. Like:
function CatInfo(GUID,Cat)
for i=1, #TestTable do
if TestTable[i] == GUID then
for j=1, TestTable[i][GUID] do
if TestTable[i][GUID][j] == Cat then
return TestTable[i][GUID][Cat].A -- returns value "A"
end
end
end
end
end
So that when I use this function, I can do something like this:
CatInfo(destGUID2,catagory1) -- returns "1"
Given your table structure, you don't need to do any looping; you can simply return the value from the table based on GUID and the category:
TestTable = {
destGUID1 = {catagory1 = {A=1,B=5,C=3},catagory2 = {A=5,B=3,C=2}},
destGUID2 = {catagory1 = {A=1,B=5,C=3},catagory2 = {A=5,B=3,C=2}}
}
function CatInfo(GUID,Cat)
return TestTable[GUID][Cat].A
end
print(CatInfo('destGUID2','catagory1'))
This will print 1. Note that destGUID2 and catagory1 need to be in quotes as those are strings.

Create a numerical table from the values of a non numerical table

Backpack = {Potion = 'backpack',Stack = 'bag',Loot = 'derp', Gold = 'random'}
Backpack[1] ~= 'backpack' -- nope
As you guys can see, I cannot call Backpack[1] since its not a numeral table, how would I generate a table after the construction of Backpack, consisting only of it's values? for example:
Table_to_be_Constructed = {Value of Potion,Value of Stack,Value of Loot,Value of Gold} -- this is what i need
It seems simple but I couldn't find a way to do it.
I need it this way because i will run a numeric loop on Table_to_be_Constructed[i]
To iterate over all the key-value pairs in a table, use the pairs function:
local Table_to_be_Constructed = {}
for key, value in pairs(Backpack) do
table.insert(Table_to_be_Constructed, value)
end
Note: the iteration order is not defined. So, you might want to sort Table_to_be_Constructed afterwards.
By convention, the variable name _ is used to indicate a variable who's value won't be used. So, since you want only the values in the tables, you might write the loop this way instead:
for _, value in pairs(Backpack) do
For the updated question
Backpack has no order (The order in the constructor statement is not preserved.) If you want to add an order to its values when constructing Table_to_be_Constructed, you can do it directly like this:
local Table_to_be_Constructed = {
Backpack.Potion,
Backpack.Stack,
Backpack.Loot,
Backpack.Gold
}
Or indirectly like this:
local items = { 'Potion', 'Stack', 'Loot', 'Gold' }
local Table_to_be_Constructed = {}
for i=1, #items do
Table_to_be_Constructed[i] = Backpack[items[i]]
end

Can a Rails `where` query with question marks be done more elegantly?

Let's say you have a simple query in Rails which goes like this
a = 42
Klass.where("`column_1` = ? OR `column_2` = ? OR `column_3` = ?", a, a, a)
Can this be done more elegantly so that you don't need to type a, a, a three times? It works fine but it looks horrible.
Can try something like this
Klass.where(["`column` = :a OR `column` = :a OR `column` = :a", { a: user_name }])
No you cannot do this more elegantly.
I'm guessing your columns should all be different columns, right? Please be more specific in your question.
You can only simplify the statement if the columns are the same and the values are different.
abc = [42,21,84]
Klass.where("column IN (?)", abc)
Personally I will use a find by with a in condition such as:
Klass.find_all_by_column([1, 2, 3])
Replace 'column' with column name you wish to search in.
Replace 1,2,3 by your value, it's an array you can add or remove values from it.
My example will generate a SQL query such as:
SELECT * FROM Klass WHERE Klass.column IN (1,2,3)
More on this on Active record documentation.
Maybe your line
Klass.where("`column` = ? OR `column` = ? OR `column` = ?", a, a, a)
can be changed into
Klass.where(["`column` = ? OR `column` = ? OR `column` = ?"] + a*3)

How to quickly initialise an associative table in Lua?

In Lua, you can create a table the following way :
local t = { 1, 2, 3, 4, 5 }
However, I want to create an associative table, I have to do it the following way :
local t = {}
t['foo'] = 1
t['bar'] = 2
The following gives an error :
local t = { 'foo' = 1, 'bar' = 2 }
Is there a way to do it similarly to my first code snippet ?
The correct way to write this is either
local t = { foo = 1, bar = 2}
Or, if the keys in your table are not legal identifiers:
local t = { ["one key"] = 1, ["another key"] = 2}
i belive it works a bit better and understandable if you look at it like this
local tablename = {["key"]="value",
["key1"]="value",
...}
finding a result with : tablename.key=value
Tables as dictionaries
Tables can also be used to store information which is not indexed
numerically, or sequentially, as with arrays. These storage types are
sometimes called dictionaries, associative arrays, hashes, or mapping
types. We'll use the term dictionary where an element pair has a key
and a value. The key is used to set and retrieve a value associated
with it. Note that just like arrays we can use the table[key] = value
format to insert elements into the table. A key need not be a number,
it can be a string, or for that matter, nearly any other Lua object
(except for nil or 0/0). Let's construct a table with some key-value
pairs in it:
> t = { apple="green", orange="orange", banana="yellow" }
> for k,v in pairs(t) do print(k,v) end
apple green
orange orange
banana yellow
from : http://lua-users.org/wiki/TablesTutorial
To initialize associative array which has string keys matched by string values, you should use
local petFamilies = {["Bat"]="Cunning",["Bear"]="Tenacity"};
but not
local petFamilies = {["Bat"]=["Cunning"],["Bear"]=["Tenacity"]};

how can I assign table names to variables?

I have a table in lua with some data.
sometable = {
{name = "bob", something = "foo"},
{name = "greg", something = "bar"}
}
I then want to loop through the table and assign a number to each name as a variable. New to lua and tried it like this.
for i,t in ipairs(sometable) do
t.name = i
end
I was then assuming print("name1", bob) would give me name1 = 1. Right now I'm getting nil. So I'm back to my ugly static list of variables till some kind soul tells me how I'm an idiot.
> sometable = {{name = "bob", something = "foo"},{name = "greg", something = "bar"}}
> for i,t in ipairs(sometable) do t[t.name] = i end
> for i,t in ipairs(sometable) do for j,u in pairs (t) do print (j,u) end end
name bob
something foo
bob 1
greg 2
something bar
name greg
> return sometable[1].bob
1>
The ipairs function will iterate only through numerically indexed tables in ascending order.
What you want to use is the pairs function. It will iterate over every key in the table, no matter what type it is.

Resources