So I have this list
numbers = { "one", "two", "three" }
and I'm trying to print it out as
The table "numbers" contains the following entries: one, two, three
what I can't figure out is how to convert the table name to a string to print it out the way I want it to. This is what I've tried so far:
function displayList(name)
listName = tostring(name) -- I've also tried tostring(self)
echo("The contents of \""..listName.."\" are: "..table.concat(name, ", "))
end
and this returns The contents of "table: 0000000000eb9c30" are: one, two, three or The contents of "nil" are: one, two, three if I use tostring(self) instead.
the goal is to be able to print any list I put in the function so I don't want to hard-code "numbers" in there. I would greatly appreciate the help as I feel like I've hit a brick wall with this.
Well in your example, if you refer to the table with a name you could as well just print that name.
So just call something like displayList("numbers", numbers)
For global tables you could do build a lookup table like
local nameLUT = {}
for k,v in pairs(_G) do
nameLUT[v] = k
end
So
numbers = {1,2,3}
print(nameLUT[numbers])
would print "numbers"
A better approach would be to give your table a name via a metamethod.
function nameTable(t, name)
return setmetatable(t, {__tostring = function() return name end})
end
numbers = nameTable({"one", "two", "three"}, "numbers")
print("Table " .. tostring(numbers) .. " contains " .. table.concat(numbers, ", "))
Of course you can use string.format for more advanced formatting or have __tostring even print the contents for you.
Related
Example:
mytable = {{id=100,wordform="One Hundread"},{id=200,wordform="Two Hundread"}}
I want to be able to access the row based on the id to do something like this:
mynum = 100
print ("The value is " .. mytable[mynum].wordform)
The main point here is I want to be able to set the index value so I can predictably retrieve the associated value later as I might do with a java hashmap.
Ideally your table should just use the ID as key:
local mytable = {[100] = {wordform = "One hundred"}, [200] = {wordform = "Two hundred"}}
print("The value is " .. mytable[100].wordform)
If your table is in list form, you can convert it to ID form rather easily:
local mytable_by_id = {}
for _, item in pairs(mytable) do mytable_by_id[item.id] = item end
Using the hash part of a Lua table is definitely preferable over looping over the list entries in linear time as Renshaw's answer suggests (the fact that it's hidden behind a metatable may hide the poor performance and trick the reader into believing a hash indexing operation is taking place here though).
Furthermore, that answer won't even work correctly, as the list part uses integer keys as well; IDs that are valid list part indices would possibly return the wrong element. You'd have to use a function instead of a metatable.
you can use metatable
setmetatable(mytable, {__index = function(tbl, id)
for _, item in pairs(tbl) do
if type(item) == "table" and item.id == id then
return item
end
end
end})
then
mynum = 100
print ("The value is " .. mytable[mynum].wordform) -- The value is One Hundread
Okay, so i've looked around everywhere on stackoverflow for a answer to this burning question.
So the issue i am having is i wanna iterate/loop thru tables.
But my tables that i take from DB in to lua is looking like this:
{"cid":"12"}{"cid":"13"}
I usually loop it like
for k, v in pairs(table) do
end
Both are in a row like that, so how would i iterate thru them? to find if a number matches the employees number..?
Given a table like this:
local t = {{cid = "12"},{cid = "13"}}
local employeeNumber = "13"
You would probably not iterate through the inner tables as they only have a single field which you can simply index.
for i,v in ipairs(t) do
if v.cid == employeeNumber then
print("match at field " .. i)
end
end
Aside that nested tables are traversed using nested loops.
I have a table which will be used to store each players name, id and another value
{
{
rpname = "name",
SteamID = "STEAM_0:0:",
giftsFound = "1",
},
The table is being sent from server to client via net.ReadTable()
I want to be able to choose each value seperatley but when I have tried the following below it only returns the first letter of every value instead of the first value
for k, v in pairs(tableData) do
for k, v in pairs(v) do
print(v[1]
end
end
Please could somebody help me out?
If I understood correctly, the sample table you wrote in the first block of code would be what you called tableData in the second, right? So, what you want to have is:
An array of players
Each entry in this array is a table
A way of getting each field of each player
With a few tweaks we can make your code more readable and, from that, correct it. Firsly, I would rename some things:
Rename your table players, for it is an array of players
local players = {
{
rpname = "john",
SteamID = "STEAM_0:0:1",
giftsFound = "4",
},
-- [...]
}
Rename your variables in the for-loop
In Lua it is common pratice to use _ to name variable we are not going to use. In this case, the key (originally named k) is not something we will use.
Since it is a list of players, each entry is a player, so it is logical to rename the variable v to player.
Also, I changed pairs() to ipairs() and there's a good reason for that. I won't cover it here, but here it is explained as best as I could. Rule of thumb: if your table is array-like, use ipairs(); else, use pairs().
for _, player in ipairs(players) do
-- [...]
end
For the nested for-loop, it does make sense using k, v and pairs, so it would be something like this:
for k, v in pairs(player) do
print(k,v)
end
Running the full piece would produce this:
rpname john
giftsFound 4
SteamID STEAM_0:0:1
I suppose it solves your problem. The real errors in your code were the way you tried to access the nested table field and, arguably, naming variables with names you have already used (k and v) in the same scope, which is, in the best case, misleading.
If you want to access a specific field in the table, instead of going through the whole thing, you can do:
-- To print every player's name
for _, player in ipairs(players) do
local name = player.rpname
print(name)
end
Or even:
-- To get the first player's (in the array) name
local name = players[1].rpname
One last thing: "Lua" is not an acronym, you don't need to use all capital letters. Lua was created in Brazil and here we speak portuguese. Lua means Moon in portuguese.
Let's say I have an URL like: http://ip/rgb/color?R=200&G=100&B=300
How would I get the values of R, G and B into seperate variables? I've looked into g.sub but I still dont get it at all, the explanations were just code with no further words on how anything works.
Use string.match and patterns:
local url = "http://ip/rgb/color?R=200&G=100&B=300"
local r,g,b= url:match("R=(%d+)&G=(%d+)&B=(%d+)")
print (r,g,b)
Here is a more general solution that stores the fields and values in a table without having to know the names or the order of the fields:
S=[[
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwjGpbabuLDTAhUD5iYKHe2LAzcQFgglMAA&url=http%3A%2F%2Fwww.eluaproject.net%2F&usg=AFQjCNHWegTT2pHkN8L75iW2UZBA5_pOMQ&sig2=VxlaLWBWD81Hp8KF8ijw1Q
]]
t = {}
S = S:match(".-?(.*)$") .. "&"
for k,v in S:gmatch("(.-)=(.-)&") do
t[k]=v
print(k,v)
end
It first gets the list of arguments (everything after the first ?), adding & at the end for uniformity. Then all key-value pairs are of the form key=value&.
Applying this code to your URL, you'll get t.R, t.G, t.B.
I am interested in inserting a table within a table in lua
mytable1={"apple","banana","grape"}
mytable2={"one","two","three"}
I want to insert mytable2 in position 4 of mytable1... so after the merger it should look somewhat like this
mytable1={"apple","banana","grape",{"one","two","three"}}
So far I tried it this way:
table.insert(mytable1,4,mytable2)
print(mytable[4])
the result is
table: 0x900b128 instead of mytable2..
I am quite confused.Please advice me where I am doing wrong and what is the right way to proceed.
this is how printing of a table works. Try out print(mytable1) or print(mytable2) and you see a similar output. You used the correct way of inserting that table. Just try out print(table1[4][1]). it should print "one"
Or to get all values try:
for index, value in ipairs(table1[4]) do
print(value);
end
this will print "one", "two" and "three"
Is possible:
tTable = { "apple", "banana", "grape", {"one", "two", "three"}}
tTable[1]
> apple
tTable[4][1]
> one
Print on table does not return it's values, but the indication that's it is a table and it's address.
Source: table inside table in Lua
Suppose you want to simply display everything in your table:
tTable = { "apple", "banana", "grape", {"one", "two", "three"}}
for k,v in pairs(tTable) do
if type(k) == "table" then
for _,i in ipairs(k) do
print(i)
end
else
print(v)
end
end
> apple
> banana
> grape
> one
> two
> three
You've done it correctly; You're just making incorrect assumptions about values, variables and print.
mytable2 is a variable name. You generally won't see variable names as strings except if you are debugging.
A table is a value. No value has a name. table.insert adds a value (or value reference) to a table. In this case, the value is a table so a reference to it is added to the table referenced by the mytable1 variable.
print calls tostring on its arguments. tostring on a table value returns what amounts to a unique identifier. print(mytable2) would print the same string as print(mytable1[4]) because both reference the same table.