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
➜ Maintaining Lua array order for a priority queue?
Maintaining Lua array order for a priority queue?
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Rivius
(99 posts) Bio
|
Date
| Wed 20 Apr 2011 02:49 PM (UTC) Amended on Wed 20 Apr 2011 02:50 PM (UTC) by Rivius
|
Message
| I basically have a function that adds values to an array and performs functions on it, but I wish to perform these functions in the order that they appear. Here is an example:
test = {}
test["apples"] = "fruit"
test["spider"] = "insect"
test["dog"] = "pet"
for a,b in pairs (test) do
print(a)
end
Will not return a print in the order that I made the table. Is there a good, simple way to keeping these organized so that I can make a priority queue for my curing?
| Top |
|
Posted by
| Twisol
USA (2,257 posts) Bio
|
Date
| Reply #1 on Wed 20 Apr 2011 06:29 PM (UTC) |
Message
| Tables are inherently orderless. You'll want to use numeric indices if you want any kind of order:
local test = {}
test[#test+1] = {"apples", "fruit"}
test[#test+1] = {"spider", "insect"}
test[#test+1] = {"dog", "pet"}
for a,b in ipairs(test) do
print(b[1])
end
Of course, this means "apples", "spider", and "dog" are no longer keys, but if you have a priority queue I don't expect you want to get things by particular keys and you just want to go in order. Also, ipairs() is an iterator that goes from test[1], test[2], etc. to the first entry that's nil (which in this case would be test[4]) |
'Soludra' on Achaea
Blog: http://jonathan.com/
GitHub: http://github.com/Twisol | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #2 on Thu 21 Apr 2011 12:42 AM (UTC) |
Message
|
In there it describes the "pairsbykeys" module. That ships with MUSHclient.
Example:
require "pairsbykeys"
test = {}
test["apples"] = "fruit"
test["spider"] = "insect"
test["dog"] = "pet"
for a,b in pairsByKeys (test) do
print(a)
end
Output:
(re-reads initial post)
Well in your case, as Twisol said, you just do a table.insert (or his technique):
local test = {}
table.insert (test, {"apples", "fruit"})
table.insert (test, {"spider", "insect"})
table.insert (test, {"dog", "pet"})
for a,b in ipairs(test) do
print(b[1])
end
Output:
The Lua developers recommend Twisol's approach, personally I think table.insert makes your intentions clearer.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Twisol
USA (2,257 posts) Bio
|
Date
| Reply #3 on Thu 21 Apr 2011 03:07 AM (UTC) |
Message
| As it happens, I just forgot what the function was called. :D |
'Soludra' on Achaea
Blog: http://jonathan.com/
GitHub: http://github.com/Twisol | Top |
|
Posted by
| Rivius
(99 posts) Bio
|
Date
| Reply #4 on Thu 21 Apr 2011 01:09 PM (UTC) |
Message
| Hrm. Alrighty. Feels a bit messy, but I'll play around with it and see if I have any further questions. Thanks guys :) | Top |
|
Posted by
| Rivius
(99 posts) Bio
|
Date
| Reply #5 on Sat 23 Apr 2011 04:39 PM (UTC) |
Message
| Alright, how about doing it this way then.
affs = {}
cures = {}
queue =
{
"health_low",
"mana_low",
"paralysis",
"health_medium",
"mana_medium"
}
cures["health_low"] = "sip health"
cures["mana_low"] = "sip mana"
cures["paralysis"] = "focus body"
for a in ipairs (queue) do
if affs[queue[a]] then
send(cures[[queue[a]])
end
end
it seems to be curing fine and in order, but with such a small queue I'm wondering if it's partially by luck, but someone said ipairs with a simple table with no keys keeps it in order. Is this true? If so, I might just use that solution instead.
One thing I was wondering is if I had multiple cures listed though like:
cures["paralysis"] = {focus body, sip allheale}
I'd want to run through that list and only send one. That is, not focus body and sip allheale at the same time for the same cure. Since I check my cures on each prompt, I'm scared I'll try to focus body on one, then sip allheale on another or even try to do both at the same time.
How would I pick just one from this new mini table? I guess I would just do another for loop inside there?
for a in ipairs cures[queue[a]] do
send(cures[queue[a]]
end
This would make it loops through all the cures in the list. I was thinking instead of sending things to the world, I'd make the keys functions in that table, and these functions would check for balances, so I wouldn't send things off balance...something like this:
function focus_body()
if balance.focus = true then
Send("focus body")
balance.focus = false
end
end
function sip_allheale()
if balance.allheale = true then
Send("sip allheale")
balance.allheale = false
end
end
cures["paralysis"] = { function () sip_allheale() end, function focus_body() end}
and then do the loop
for a in ipairs cures[queue[a]] do
cures[queue[a]]()
end
That means I'll send only the cures that are onbalance, but I'd still send them both if they were offbalance. I'm also thinking that maybe my inexperience with lua makes it hard to see a better way that a for loop within a for loop, so is there a better way?
Final code would end up like this:
affs = {}
cures = {}
queue =
{
"health_low",
"mana_low",
"paralysis",
"health_medium",
"mana_medium"
}
function focus_body()
if balance.focus = true then
Send("focus body")
balance.focus = false
end
end
function sip_allheale()
if balance.allheale = true then
Send("sip allheale")
balance.allheale = false
end
end
cures["paralysis"] = { function () sip_allheale() end, function focus_body() end}
for a in ipairs (queue) do
if affs[queue[a]] then
for a in ipairs cures[queue[a]] do
(cures[queue[a]]()
end
end
end
looks sloppy, and I'm sure I'll be trying to cure the same twice. | Top |
|
Posted by
| Nick Gammon
Australia (23,046 posts) Bio
Forum Administrator |
Date
| Reply #6 on Sat 23 Apr 2011 11:49 PM (UTC) |
Message
| Try indenting, it makes debugging so much easier:
affs = {}
cures = {}
queue =
{
"health_low",
"mana_low",
"paralysis",
"health_medium",
"mana_medium"
}
function focus_body()
if balance.focus = true then
Send("focus body")
balance.focus = false
end
end
function sip_allheale()
if balance.allheale = true then
Send("sip allheale")
balance.allheale = false
end
end
cures["paralysis"] = {
function ()
sip_allheale()
end,
function
focus_body()
end}
for a in ipairs (queue) do
if affs[queue[a]] then
for a in ipairs cures[queue[a]] do
(cures[queue[a]]()
end
end
end
I don't think what you have is too bad, the inner loop is just iterating through a short list of functions you want to perform. |
- 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.
23,665 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top