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.
Related
Is it possible to have a function that can access arbitrarily nested entries of a table?
The following example is just for one table. But in my real application I need the function to check several different tables for the given (nested) index.
local table1 = {
value1 = "test1",
subtable1 = {
subvalue1 = "subvalue1",
},
}
local function myAccess(index)
return table1[index]
end
-- This is fine:
print (myAccess("value1"))
-- But how do I access subtable1.subvalue1?
print (myAccess("subtable1.subvalue1???"))
You won't be able to do this using a string unless you use load to treat it as Lua code or make a function to walk on a table.
You can make a function which will split your string by . to get each key and then go one by one.
You can do this using gmatch + one local above gmatch with current table.
#Spar: Is this what you were suggesting? It works anyway, so thanks!
local table1 = {
value1 = "test1",
subtable1 = {
subvalue1 = "subvalue1",
},
}
local function myAccess(index)
local returnValue = table1
for key in string.gmatch(index, "[^.]+") do
if returnValue[key] then
returnValue = returnValue[key]
else
return nil
end
end
return returnValue
end
-- This is fine:
print (myAccess("value1"))
-- So is this:
print (myAccess("subtable1.subvalue1"))
Hello i have got a table, that uses string indexes:
shirt = {
["shirtwhite.png"] = "shirt_white.png",
["shirtwhite.png^[multiply:#3f3f3f"] = "shirt_white.png^[multiply:#3f3f3f",
["shirtwhite.png^[multiply:#ff0000"] = "shirt_white.png^[multiply:#ff0000",
["shirtwhite.png^[multiply:#ff7f00"] = "shirt_white.png^[multiply:#ff7f00",
["shirtwhite.png^[multiply:#ffff00"] = "shirt_white.png^[multiply:#ffff00",
["shirtwhite.png^[multiply:#00ff00"] = "shirt_white.png^[multiply:#00ff00",
["shirtwhite.png^[multiply:#0000ff"] = "shirt_white.png^[multiply:#0000ff",
["shirtwhite.png^[multiply:#9f00ff"] = "shirt_white.png^[multiply:#9f00ff",
},
Theese are t-shirt-textures for an editable game-character-skin (with colour-values for different colors).
There are some more of theese tables in the code, for other parts of the character-skin
how can I keep the table in it´s shown order, while it´s loaded in this code-snippet?
The tzables are in a file "skins.lua" and the code-snippet is from another lua-file
character_creator = {}
character_creator.skins = dofile(minetest.get_modpath("character_creator") .. "/skins.lua")
local skins = character_creator.skins
local skins_array = {}
minetest.after(0, function()
local function associative_to_array(associative)
local array = {}
for key in pairs(associative) do
table.insert(array, key)
end
return array
end
skins_array = {
skin = associative_to_array(skins.skin),
hair = associative_to_array(skins.hair),
eyes = associative_to_array(skins.eyes),
shirt = associative_to_array(skins.shirt),
pants = associative_to_array(skins.pants),
}
end)
In Lua only arrays (positive integer-indexed tables) have "order" (can be iterated using ipairs); the hash tables (like the one you are working with) are unordered. If you want to iterate over a table like this in a specific order, you'd usually create an array with the keys, sorted them in the order you want and then iterate over that array extracting elements from your table.
There are also components (like ordered table) that may keep track of insertions and return results in the same order, if that's what you want.
In the command
table.insert(table, data)
how can you use that but for the inserts have string keys?
PSEUDO CODE
tableOfStuff = {cat, pig, hat, lemon}
t = {}
for i=1, #tableOfStuff do
table.insert(t, key=tableOfStuff[i], data=tableOfStuff[i])
end
So I end up with a table...
t['cat'] == 'cat'
t['dog'] == 'dog'
etc.....
EDIT
I think my example confused people... I am asking how to use "insert.table" but insert tings with string keys...
table.insert(table,data,stringkey)
something like this?
Creating One Table
If all you want is to create a table with strings as keys, then check out Table Constructors, you have a couple options.
Option 1:
t = { key1 = "value1", key2 = "value2" }
--or like this:
t = { ["key1"] = "value1", ["key2"] = "value2" }
Option 2: (create an empty table first)
t = {}
t.key1 = "value1"
--or like this
t["key2"] = "value2"
It looks like you want the keys and values to be the same string and that is possible. Just write the same thing for key1 and value1. So t["cat"] = "cat".
Using Two Tables
Based on your example code, it looks like you want to take an existing table of strings and create from that a new table with strings as both the keys and the values. To do that:
table1 = { "cat", "pig", "hat", "lemon" }
table2 = {}
for i=1, #table1 do
table2[ table1[i] ] = table1[i]
end
--test
print table2["cat"]
Here is a good lesson about tables in Lua: Lua Tables Tutorial
The comment is right.You needn't and you can't use table.insert.You can see the document table.insert.It's only support the number.It' used for the array part of table.But you're using the hash part of a table.
code:
tableOfStuff = {"cat", "pig", "hat", "lemon"}
t = {}
for i=1, #tableOfStuff do
local szKey = tableOfStuff[i];
t[szKey] = tableOfStuff[i]; -- the value can be the others.
end
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
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"].