I want to store a lua table where the keys are other lua tables. I know that this is possible BUT I want to be able to do look ups in the table using copies of those tables. Specifically, I want to be able to do:
t = {}
key = { a = "a" }
t[key] = 4
key2 = { a = "a" }
and then I want to be able to look up:
t[key2]
and get 4.
I know that I can turn key into a string and put it into table t. I’ve also thought about writing a custom hash function or doing this by nesting tables. Is there a best way for me to get this type of functionality? What other options do I have?
In Lua, two tables created separately are considered “different”. But if you create a table once, you can assign it to any variables you want, and when you compare them, Lua will tell you that they are equal. In other words:
So, that’s the simple, clean way of doing what you want. Store
keysomewhere, so you can retrieve the4back by using it. This is also very fast.If you really don’t want to do that … well, there is a way. But it is kindof inefficient and ugly.
The first part is making a function that compares two separate tables. It should return true if two tables are “equivalent”, and false if they are not. Let’s call it equivalent. It should work like this:
The function must be recursive, to handle tables that contain tables themselves. It also must not be fooled if one of the tables “contains” the other, but has more elements. I came out with this implementation; probably there are better ones out there.
I’m not going to explain that function here. I hope it is clear enough what it does.
The other part of the puzzle consist on making
tuse theequivalentfunction when comparing keys. This can be done with careful metatable manipulation, and an extra “storage” table.We basically transform
tinto an impostor. When our code tells it to store a value under a key, it doesn’t save it in itself; instead it gives it to the extra table (we’ll call thatstore). When the code askstfor a value, it searches for it instore, but using theequivalentfunction to get it.This is the code:
Usage example: