Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, 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
➜ Using Lua table references.
Using Lua table references.
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Blainer
(191 posts) Bio
|
Date
| Thu 26 Nov 2009 12:51 AM (UTC) |
Message
| If I have:
main_table = {a_key={"v"}, another_key={"val"}}
sorted_table = {}
sorted_table[1] = main_table.another_key
sorted_table[2] = main_table.a_key
Now if I want to delete all references to another_key is there a way to do that with out looping sorted_table.
I messed around with rawget and rawset. My understanding of the manual is if I change an object with rawset using the objects rawget name then all objects referencing that object will have that new value.
rawset (_G, rawget (main_table, "another_key"), nil)
This doesn't work at all.
| Top |
|
Posted by
| WillFa
USA (525 posts) Bio
|
Date
| Reply #1 on Thu 26 Nov 2009 01:12 AM (UTC) Amended on Thu 26 Nov 2009 01:13 AM (UTC) by WillFa
|
Message
| Rawget and Rawset just bypass any metatables with __index and __newindex values.
master = {key="Hi"}
child = {}
setmetatable (child, {__index = master})
print (child.key) -- "Hi"
print (rawget(child,key)) -- nil
I don't know of a way to delete all references without a lot of loops. | Top |
|
Posted by
| Nick Gammon
Australia (23,122 posts) Bio
Forum Administrator |
Date
| Reply #2 on Thu 26 Nov 2009 02:21 AM (UTC) |
Message
| This may not answer your question, but if you store in the sorted table the keys in the main table, and not the values, you can get back into the main table more easily. For example:
main_table = {
key1 = "the",
key2 = "brown",
key3 = "fox",
key4 = "jumped",
key5 = "over",
key6 = "a",
key7 = "lazy",
key8 = "dog",
}
-- add to another table for sorting
sorted_table = {}
for k in pairs (main_table) do
table.insert (sorted_table, k)
end -- for
-- sort based on the value of the key, not the key itself
table.sort (sorted_table, function (a, b) return main_table [a] < main_table [b] end )
-- show in sorted order
for k, v in ipairs (sorted_table) do
print (main_table [v])
end -- for
-- I want to get rid of item 3 in the sorted table
k = sorted_table [3] -- what key is it?
-- remove from sorted table
table.remove (sorted_table, 3)
-- remove from main table
main_table [k] = nil
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,122 posts) Bio
Forum Administrator |
Date
| Reply #3 on Thu 26 Nov 2009 02:23 AM (UTC) Amended on Thu 26 Nov 2009 02:25 AM (UTC) by Nick Gammon
|
Message
| Or, more simply, as table.remove returns the removed value:
-- remove from sorted table
k = table.remove (sorted_table, 3) -- k is now the key
-- remove from main table
main_table [k] = nil
And I suppose you could combine those 2 lines:
main_table [table.remove (sorted_table, 3)] = nil
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Terry
USA (87 posts) Bio
|
Date
| Reply #4 on Thu 26 Nov 2009 02:32 AM (UTC) Amended on Thu 26 Nov 2009 02:33 AM (UTC) by Terry
|
Message
| I just did some fooling around with tables, and came up with this.
main_table = { }
main_table.a_key = { "v" }
main_table.another_key = { "val" }
print(main_table.a_key[1])
print(main_table.another_key[1])
table.remove(main_table.another_key)
print(main_table.a_key[1])
print(main_table.another_key[1])
The one absolutely major drawback, in my eyes, is the need to make each key a single-element array, instead of just a value.
For example:
main_table =
{
["a_key"] = "v",
["another_key"] = "val"
}
print(main_table["a_key"])
print(main_table["another_key"])
table.remove(main_table["another_key"])
print(main_table["a_key"])
print(main_table["another_key"])
*****
Run-time error
Immediate execution
[string "Immediate"]:10: bad argument #1 to 'remove' (table expected, got string)
stack traceback:
[C]: in function 'remove'
[string "Immediate"]:10: in main chunk
Also, since table.remove is literally looping through anyway, and just hiding it behind a rather painful method, I think it'd be much clearer to loop directly.
Edit: Of course nick would post while I answer :-D | Top |
|
Posted by
| Blainer
(191 posts) Bio
|
Date
| Reply #5 on Thu 26 Nov 2009 03:37 AM (UTC) |
Message
| Getting into main_table is not the problem it's finding the index in sorted_table I want to make faster.
main_table["unique_id_1"] = { id = "unique_id_1", desc = "a mean dog" }
main_table["unique_id_2"] = { id = "unique_id_2", desc = "a happy dog" }
sorted_table[1] = main_table.unique_id_2
sorted_table[2] = main_table.unique_id_1
main_table is keyed by the items unique id to enable easy look up when I have the item id. sorted_table
is in the order of these items from the MUD.
Now if I have the id I can get the item table easily from the main_table but when I need to remove
that item all together and keep the sorted_list in the order it came from the MUD I need to know the
table index of the item in sorted_table
At the moment I do this:
wanted_id = "unique_id_1"
main_table[wanted_id] = nil
for i,v in ipairs(sorted_table) do
if wanted_id == v.id then
table.remove (sorted_table, i)
return
end
end
This works but if you get 50 items to be removed at once and a large table it can get out of hand.
You might do 100 tests to find each item. | Top |
|
Posted by
| Nick Gammon
Australia (23,122 posts) Bio
Forum Administrator |
Date
| Reply #6 on Thu 26 Nov 2009 05:38 AM (UTC) |
Message
|
Quote:
main_table["unique_id_1"] = { id = "unique_id_1", desc = "a mean dog" }
main_table["unique_id_2"] = { id = "unique_id_2", desc = "a happy dog" }
sorted_table[1] = main_table.unique_id_2
sorted_table[2] = main_table.unique_id_1
This isn't exactly what I suggested. I don't see how you can quickly get back to the main table here (you actually have a copy of the table entry, not the key itself).
To keep the key you would do:
Quote:
sorted_table[1] = "unique_id_2"
sorted_table[2] = "unique_id_1"
However your method might make it easier anyway. Since you have a copy of the *reference to* the table in the main table, then you can simply empty out the table item (don't replace it, that would cause a new table to be created).
So, for example:
t = main_table["unique_id_1"]
for k in pairs (t) do
t [k] = nil
end -- for
Now t is empty but not nil. Now you can set it to nil:
main_table["unique_id_1"] = nil
That gets rid of it from the main table. Now later on you simply go through the sorted table and remove any table items that happen to have no elements. And before you do that you allow for (eg. for display purposes) that a table element with no items, is to be considered non-existent.
Another approach would be to store, in the main table, the key it belongs to in the sorted table.
Yet another approach is to resort the sorted table when required, eg. after you know additions or deletions have been made to the main table, and a sort not done afterwards.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Blainer
(191 posts) Bio
|
Date
| Reply #7 on Thu 26 Nov 2009 07:53 AM (UTC) |
Message
| I never would have thought of that. Thank you. | 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.
25,213 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top