I tried to compare tables like this, but it didn’t work:
local table1 = {1}
local table2 = {1}
if table1 == table2 then
print("1")
end
So I got an idea to use JSONEncode which works, but I’m not sure about a few things.
local httpService = game:GetService("HttpService")
local table1 = {1}
local table2 = {1}
if httpService:JSONEncode(table1) == httpService:JSONEncode(table2) then
print("1")
end
How does JSONEncode even work? Does it send the table to some website, which converts it into JSON and returns it? Or is it all done in-game? Also, are there any better ways to compare tables, as I don’t know exactly how performant this is?
JSONEncode just transforms the table into a JSON-string format, that’s done locally as far as I’m aware. It’s just often used with http requests, hence it being a method of the service.
Converting it is most likely sub optimal, but you’d really have to try. A different approach can be iterating through one table, checking whether each index holds the same value. If either table has the next index when the other doesn’t, they aren’t the same as well. Only viable with numeric indices where the order is guaranteed the same.
t1 = {1,2,4,5}
t2 = {1,2,4,8}
if #t1 ~= #t2 then
print("Different length")
return
end
for i = 1,#t1 do
if t2[i] ~= t1[i] then
print("different at",i)
break
end
last = i
end
I knew I was oversimplifying something, thanks. It’s only viable for numeric indices but I didn’t recall in the early morning why key-value pairs could be problematic.
You could do a deep comparison, but requires doing a deep scan through both tables. And if anything is cyclical then it gets messy. JSON comparison would work assuming keys are kept in same order and data is JSONable. I would avoid the JSON method if possible, because it’s literally assuming that the string representation of both tables is the same.
The deep comparison works by:
Check that all key/values in t1 match key/values in t2
Same as above, but check t2 against t1… OR check t2 doesn’t contain keys not present in t1
local compared, ids, nxtID, cacheCmp
local function toID(t)
if not ids[t] then
ids[t] = nxtID
compared[nxtID] = true
nxtID = nxtID * 2
end
return ids[t]
end
local function cmp(src, dst)
for key, value in next, src do
local other = dst[key]
if other ~= value and not (
type(other) == 'table' and
type(value) == 'table' and
cacheCmp(other, value)
) then
return false
end
end
return true
end
function cacheCmp(a, b)
local cmpID = toID(a) + toID(b)
if compared[cmpID] then
return true
end
compared[cmpID] = true
return cmp(a, b) and cmp(b, a)
end
return function(a, b)
compared = {}
ids = {}
nxtID = 1
return cacheCmp(a, b)
end
Here is my test code:
local cmp = require(script.Parent.cmp)
-- recursive table (bad stuff)
local _666 = {}
_666[666] = _666
-- duel-recursive table
local _999 = {}
local _999_2 = {}
_999[999] = _999_2
_999_2[999] = _999
local a = {
{secret = 'hehe'};
_666;
_999;
}
local b = {
{secret = 'hehe'};
_666;
_999;
}
local c = {
{secret = 'boo'};
_666;
_999;
}
print('aa', cmp(a, a)) --> true
print('ab', cmp(a, b)) --> true
print('ac', cmp(a, c)) --> false
print('bc', cmp(b, c)) --> false