Lua Table Comparisons Within Tables
-
28-10-2019 - |
Question
So I have a table that holds references to other tables like:
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a[#a + 1] = b
end
Now if I want to see if a particular object is within "a" I have to use pairs like so:
local z = a.collection[ 99 ]
for i,j in pairs( a.collection ) do
if j == z then
return true
end
end
The z object is in the 99th spot and I would have to wait for pairs to iterate all the way throughout the other 98 objects. This set up is making my program crawl. Is there a way to make some sort of key that isn't a string or a table to table comparison that is a one liner? Like:
if a.collection[{z}] then return true end
Thanks in advance!
Solution
Why are you storing the object in the value slot and not the key slot of the table?
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a.collection[b] = i
end
to see if a particular object is within "a"
return a.collection[b]
If you need integer indexed access to the collection, store it both ways:
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a.collection[i] = b
a.collection[b] = i
end
Finding:
local z = a.collection[99]
if a.collection[z] then return true end
OTHER TIPS
Don't know if it's faster or not, but maybe this helps:
Filling:
local a = {}
a.collection = {}
for i = 1, 100 do
local b = {}
a.collection[b] = true -- Table / Object as index
end
Finding:
local z = a.collection[99]
if a.collection[z] then return true end
If that's not what you wanted to do you can break your whole array into smaller buckets and use a hash to keep track which object belongs to which bucket.
you might want to consider switching from using pairs() to using a regular for loop and indexing the table, pairs() seems to be slower on larger collections of tables.
for i=1, #a.collection do
if a.collection[i] == z then
return true
end
end
i compared the speed of iterating through a collection of 1 million tables using both pairs() and table indexing, and the indexing was a little bit faster every time. try it yourself using os.clock() to profile your code.
i can't really think of a faster way of your solution other than using some kind of hashing function to set unique indexes into the a.collection table. however, doing this would make getting a specific table out a non-trivial task (you wouldn't just be able to do a.collection[99], you'd have to iterate through until you found one you wanted. but then you could easily test if the table was in a.collection by doing something like a.collection[hashFunc(z)] ~= nil...)