Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Entire forum
➜ MUSHclient
➜ Lua
➜ Tables in Lua
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1 2
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Wed 24 Nov 2004 03:05 AM (UTC) Amended on Sat 07 Apr 2007 06:56 AM (UTC) by Nick Gammon
|
Message
| Tables are a fundamental part of the Lua design. You can make your own very easily, and store anything you like in them (including other tables).
For example, say you want to keep track of some mobs:
mobs = {} -- create mobs table
The above line creates a table, which you can then put data into, in various ways. Let's make an individual mob another table, and then store relevant parts keyed by name:
mobs.kobold = {
name = 'killer',
hp = 22,
gold = 5,
location = 'city square'
}
-- and another one ...
mobs.worm = {
name = 'gordon',
hp = 4,
gold = 15,
location = 'underground'
}
Now we can start to look at this data. First, we'll print the mobs table:
print (mobs) --> table: 00629490
You can type these examples into the MUSHclient command window (prefixed by the scripting prefix "/"), or into the Immediate scripting window.
It is all very well knowing we have a table, but what is in it? A useful feature of Lua is the "table.foreach" instruction which lets you iterate over a table. eg.
table.foreach (mobs, print)
-- output:
worm table: 006303E0
kobold table: 00630560
This is printing (ie. doing a world.Note) each entry in the table. First you see the key, and then the data. The data in this case is another table.
An alternative way of doing this is with a loop:
for k, v in pairs (mobs) do
print ("key = ", k, " value = ", v)
end
-- output:
key = worm value = table: 006303E0
key = kobold value = table: 00630560
But what is the value for the kobold? Well, we just repeat the exercise for the sub-table:
table.foreach (mobs.kobold, print)
-- output:
name killer
gold 5
location city square
hp 22
We can also access individual fields by delimiting them with dots, like this:
print (mobs.kobold.hp) --> 22
Recursive table printer
If you are playing with tables a lot, a recursive printing function might be helpful. Here is an example:
function tprint (t, indent, done)
done = done or {}
indent = indent or 0
for key, value in pairs (t) do
Tell (string.rep (" ", indent)) -- indent it
if type (value) == "table" and not done [value] then
done [value] = true
Note (tostring (key), ":");
tprint (value, indent + 2, done)
else
Tell (tostring (key), "=")
print (value)
end
end
end
To use this, just call it with a table, eg.
tprint (mobs)
-- output:
worm:
name=gordon
gold=15
location=underground
hp=4
kobold:
name=killer
gold=5
location=city square
hp=22
That is neat - now we can see the table, and any sub-tables, in a single command.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| David Berthiaume
(202 posts) Bio
|
Date
| Reply #1 on Sat 11 Dec 2004 03:21 PM (UTC) |
Message
| Where would you place the table? Obviously it wouldn't be in a trigger.... Also how to I create a Lua script file?
I used to have myscript.vbs, but with the new language, not sure how to create one. | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #2 on Sat 11 Dec 2004 09:38 PM (UTC) |
Message
| You put the table where you put other global variables. Normally that would be in your script file, so it is in the "global script spaces".
The Lua script file is just a text file. I would call it something like myscript.lua. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| David Berthiaume
(202 posts) Bio
|
Date
| Reply #3 on Sun 12 Dec 2004 12:09 AM (UTC) |
Message
| So make a text file called whatever.lua and load it like I would a whatever.vbs?
Seems simple enough, though you mentioned something about the Lua in the global preferences. Is that the same as loading a .lua script file i nthe scripting options in game>configure>scripting?
If so wouldn't there be a conflict having 2 script files?
Additionally, is loading a script file necessary if you can simply use the global preferance file? | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #4 on Sun 12 Dec 2004 01:44 AM (UTC) |
Message
|
Quote:
So make a text file called whatever.lua and load it like I would a whatever.vbs?
Yes.
Quote:
If so wouldn't there be a conflict having 2 script files?
No, they both execute in the global script space for that world, so effectively you have one set of commands followed by another.
However the global preferences was intended for setting up a secure sandbox, not to have all your scripts in it. For one thing, it is kept in the registry, and if you have thousands of lines of script in it, it will bloat the registry. Also, if you lose the registry (eg, reinstall Windows) then you have lost all your scripts.
If you must do that, put all your scripting into a file, and then in the global preferences, just do:
dofile "path_to_my_script_file.lua"
However I think the preferable thing is to simply have a script file like you do for VB and quote that file's name in the scripting preferences. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| MaXXmaster
(1 post) Bio
|
Date
| Reply #5 on Sun 30 Oct 2005 07:53 AM (UTC) Amended on Sun 30 Oct 2005 09:22 PM (UTC) by Nick Gammon
|
Message
| Hi! I've been looking for a function that has exactly the same functionality as the php function print_r (recursive printing of anything, tables, values, what ever...)
so i stumbled across your posting, with minor changes in your source, i managed to make quite a good clone of php's print_r which works fine in lua5 as well.
source:
function print_r (t, indent, done)
done = done or {}
indent = indent or 0
if type(t) == "table" then
for key, value in pairs (t) do
io.write(string.rep (" ", indent)) -- indent it
if type (value) == "table" and not done [value] then
done [value] = true
io.write(string.format("[%s] => table\n", tostring (key)));
io.write(string.rep (" ", indent+4)) -- indent it
io.write("(\n");
print_r (value, indent + 7, done)
io.write(string.rep (" ", indent+4)) -- indent it
io.write(")\n");
else
io.write(string.format("[%s] => %s\n", tostring (key),value))
end
end
else
io.write(t .. "\n")
end
end
maybe this helps any other php programmer that wants to use lua for some reason.
cheers | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #6 on Sun 30 Oct 2005 09:23 PM (UTC) |
Message
| Thanks, I amended your post to put in the [code] tag to show formatting better. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #7 on Mon 31 Oct 2005 04:25 AM (UTC) |
Message
| For more information about Lua tables, see Lua tables in detail. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Siluri
(5 posts) Bio
|
Date
| Reply #8 on Tue 28 Mar 2006 03:39 PM (UTC) |
Message
| Just starting out with LUA, I found the 2 dimension table sort topic *very* useful after searching everywhere for that info.
so a question on tables if I may...
I have a master table of players and i want to copy a sub-set of this into another table based upon a filter.
EG
mastertable[1] = {["id"]=1, ["name"]="fred", ["class"]="a"}
mastertable[2] = {["id"]=1, ["name"]="bill", ["class"]="b"}
mastertable[3] = {["id"]=1, ["name"]="john", ["class"]="a"}
mastertable[4] = {["id"]=2, ["name"]="frank", ["class"]="b"}
mastertable[5] = {["id"]=2, ["name"]="robert", ["class"]="a"}
So so way of doing a table.foreach on the mastertable, checking if the "id" == a value and then any matching records copied to a new table. If I was after "id"=2 then
copytable[1] = {["id"]=2, ["name"]="frank", ["class"]="b"}
copytable[2] = {["id"]=2, ["name"]="robert", ["class"]="a"}
The following code doesn't work although I think it's not a million miles away...
table.foreach (mastertable, function() table.insert (copytable,
function (k, v)
if v.number == id then
return k
end -- if
end -- function
end -- function
)
)
Thanks in advance.
| Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #9 on Tue 28 Mar 2006 08:08 PM (UTC) Amended on Tue 28 Mar 2006 08:09 PM (UTC) by Nick Gammon
|
Message
| I believe table.foreach is being deprecated in Lua 5.1, so you could do it in a simple loop:
copytable = {}
for k, v in ipairs (mastertable) do
if v.id == 2 then
table.insert (copytable, v)
end -- if
end -- for
That works OK, and is easy to read.
However you can certainly do it with table.foreach. I don't know why you had 2 functions, one is enough. Also I would use table.foreachi since your table seems to be numerically indexed:
copytable = {}
table.foreachi (mastertable,
function (k, v) -- key, value
if v.id == 2 then
table.insert (copytable, v)
end -- if
end -- function
) -- end foreachi
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #10 on Tue 28 Mar 2006 08:15 PM (UTC) Amended on Tue 28 Mar 2006 08:41 PM (UTC) by Nick Gammon
|
Message
| Of course, you can make a more generic "table copy" function, like this:
-- generic table filter function
function filtertable (t, f)
assert (type (t) == "table")
assert (type (f) == "function")
local k, v
local result = {}
for k, v in ipairs (t) do
if f (v) then
table.insert (result, v)
end -- if
end -- for
return result
end -- filtertable
-- example
copytable = filtertable (mastertable,
function (v) return v.id == 2 end
)
What this does is make a function that makes a copy of the supplied table, where you simply supply a function that returns true if you want the table item to be included, and false if not.
I threw in a couple of asserts to check that the arguments are what you expect. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Siluri
(5 posts) Bio
|
Date
| Reply #11 on Tue 28 Mar 2006 09:52 PM (UTC) |
Message
| fantastic!
I knew the code should be short and elegant but i had the blinkers on i suspect.
Also thanks for the warning on LUA 5.1, i will follow your advice.
:-) | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #12 on Tue 28 Mar 2006 10:05 PM (UTC) |
Message
| Also you can simplify your table definition, assuming what you did was not just an example. Instead of:
mastertable[1] = {["id"]=1, ["name"]="fred", ["class"]="a"}
mastertable[2] = {["id"]=1, ["name"]="bill", ["class"]="b"}
You can use:
mastertable[1] = {id=1, name="fred", class="a"}
mastertable[2] = {id=1, name="bill", class="b"}
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Siluri
(5 posts) Bio
|
Date
| Reply #13 on Tue 28 Mar 2006 10:06 PM (UTC) |
Message
| a follow up question!
what's the best way of emptying a table since they can't be deleted?
1. just a table.setn = 0? so the contents get's overwritten
2. do a table.remove in a foreach?
3. do a loop setting each element to null?
Thanks | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #14 on Tue 28 Mar 2006 10:38 PM (UTC) Amended on Wed 29 Nov 2006 09:29 PM (UTC) by Nick Gammon
|
Message
|
That will remove the reference to the table, and the garbage collector will collect it. Or, if you want to empty it, and keep it as a table:
mastertable = {} -- make new, empty, table
If, for some reason, you need to keep the table the same (for example, you have references to it elsewhere), you can do this:
for k in pairs (mastertable) do
mastertable [k] = nil
end -- for
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
103,389 views.
This is page 1, subject is 2 pages long: 1 2
It is now over 60 days since the last post. This thread is closed.
Refresh page
top