I am currently in a situation where I need to compare two tables to make sure they are the same (similar). Each table being compared is shallow (no nested tables). I am using the HTTP service’s json encode function to string compare the two tables but have ran into an issue regarding the index order of said tables. Below is an example of my problem.
In this case
local a = {
apple = true,
cat = true
}
local b = {
apple = true,
cat = true
}
HttpService:JSONEncode(a) == HttpService:JSONEncode(b) --true
however in this case
local a = {
apple = true,
cat = true
}
local b = {
cat = true,
apple = true
}
HttpService:JSONEncode(a) == HttpService:JSONEncode(b) --false
Is there any way to “sort” the indices of the tables so they appear similar when string comparing using json encoding? Note that the tables are shallow and do not contain any nested values.
This is a great example of the XY problem in Software engineering.
Your task is to compare the tables. You’re overcomplicating your issue by adding the random need for JSON, especially given that the tables are quite simple in nature. You can solve the problem with two loops (which would be likely faster than making 2 JSON strings)
Note: I don’t have access to Studio so my code is untested, but the general concept should work.
local function isEq(t1, t2)
for key, value in pairs(t1) do
if t2[key] ~= value then
return false
end
end
return true
end
local tablesAreEqual = isEq(a, b) and isEq(b, a)
print(tablesAreEqual)
Note: I added and isEq(b, a), because there might be keys in b that don’t exist in a (tables are not the same). If you are sure that both tables have the exact same keys, then this would be unnecessary.
Bonus answer to your actual question:
Put all key-value pairs in an array, and sort that array. Turn that array to JSON.
local function sortKVP(t)
local result = {}
for key, value in pairs(t) do
table.insert(result, { K = key, V = value })
end
table.sort(result, function(a,b) return a.K < b.K end)
return result
end
local newA = sortKVP(a)
local newB = sortKVP(b)
HttpService:JSONEncode(a) == HttpService:JSONEncode(b) --false
HttpService:JSONEncode(newA) == HttpService:JSONEncode(newB) --true
It doesn’t. Dictionaries in Lua don’t have any defined order. The Luau implementation iterates from older to newer elements, because there isn’t any specification that says that the iteration should be in alphabetical order. This is true of most popular HashMap implementations as well (e.g. Dictionary in C# and HashMap in Java iirc)
Because cat appears earlier and later in your two code snippets, the order is different, because that’s how Luau sees it. Behind the scenes, there isn’t any sorting going on, just some arbitrary order that can change at any point. “Order” really only exists for arrays (obviously).