# How do you compare two tables with equal values but different orders?

Okay, so what I want is a little different from every other answer I’ve seen for this on devforum.
Basically, I want to be able to see if two tables with nested tables have equal values but different orders.
So for example, this is table 1.

{
"a",
1,
{"e","2"}
}

And this is table 2.

{
{"2","e"},
"a",
1
}

They both have equal values as you can see, but they have different orders.

Oh and another thing
I don’t want it to be completely random, like values must be equal inside of nested tables.
For example, these two tables won’t work.

t1 = {
"a",
1,
{"e","2"}
}
t2 = {
"e",
1,
{"a","2"}
}

You can something like this:

function areEqualTables(tab1, tab2)
local equal = true
for v, i in pairs(tab1) do
local isIn = false
for r, e in pairs(tab2) do
if e == i then
isIn = true
end
end
if not isIn then
equal = false
break
end
end
return equal
end
1 Like

It doesn’t work properly.
As you can see these tables are clearly not the same but it still prints true

function areEqualTables(tab1, tab2)
if #tab1 < #tab2 then
local new = tab1
tab1 = tab2
tab2 = new
end
local equal = true
for v, i in pairs(tab1) do
local isIn = false
for r, e in pairs(tab2) do
if e == i then
isIn = true
end
end
if not isIn then
equal = false
break
end
end
return equal
end

have you tried using the

table.find()

function to check if the other table has the same value that you detected?

Now it returns false when it should be true

function areEqualTables(tab1, tab2)
if #tab1 < #tab2 then
local new = tab1
tab1 = tab2
tab2 = new
end
local equal = true
for v, i in pairs(tab1) do
local isIn = false
for r, e in pairs(tab2) do
if e == i then
isIn = true
end
end
if not isIn then
equal = false
break
end
end
return equal
end
local t1={"a","b",{1,2}}
local t2 = {"b","a",{1,2}}
print(areEqualTables(t1,t2))

First upack the table and the new unpacked table use it in the compare function

function unpackTable(tab)
local new = {}

for v, i in pairs(tab) do
table.insert(new, i)
if type(i) == type({}) then
local otherTab = unpackTable(i)
for r, e in pairs(otherTab) do
table.insert(new, e)
end
end
end

return new
end

print(areEqualTables(unpackTable(t1),unpackTable(t2)))

That won’t work because if we have these two tables

t1 = {
1,
2,
{"a","b"}
}
t2 = {
1,
2,
"a",
"b"
}

It’ll say both tables are equal when they aren’t

local table1 = {1, 2, 3}
local table2 = {"a", 2, 3}

local function CompareTables(t1, t2)
if #t1 ~= #t2 then
return false
end

for i = 1, #t1 do
local v1 = t1[i]
local v2 = t2[i]
if v1 ~= v2 then
return false
end
end
return true
end

print(CompareTables(table1, table2))

It doesn’t work with nested tables.

local table1 = {1, 2, 3}
local table2 = {{1, 2}, 2, 3}

This printed false for me (with my function)

local table1 = {1, 2, {"b","a"}}
local table2 = {1, 2, {"a","b"}}

local function CompareTables(t1, t2)
if #t1 ~= #t2 then
return false
end

for i = 1, #t1 do
local v1 = t1[i]
local v2 = t2[i]
if v1 ~= v2 then
return false
end
end
return true
end

print(CompareTables(table1, table2))

This prints false as well which shouldn’t be the case.

Oh I didn’t know you wanted that. I’ll write something.

Sorting copies of both tables and comparing the values in order should be reasonably fast, so long as elements of the same type are equal when their strings are equal.

local HttpService = game:GetService("HttpService")

local function order(t)
local copy = {}
for k, v in pairs(t) do
copy[k] = type(v) == "table" and order(v) or v
end
table.sort(copy, function(a, b)
if type(a) ~= type(b) then return type(a) > type(b) end
if type(a) == "table" then
return HttpService:JSONEncode(a) > HttpService:JSONEncode(b)
end
end)
return copy
end

function equal(a, b)
if #a ~= #b then return false end
local copy_a = order(a)
local copy_b = order(b)
for i = 1, #copy_a do
if type(copy_a[i]) ~= type(copy_b[i]) then return false end
if type(copy_a[i]) == "table" then
if not equal(copy_a[i], copy_b[i]) then return false end
elseif copy_a[i] ~= copy_b[i] then
return false
end
end
return true
end

example:

local a = {"b", "a", 3, {2, 1}}
local b = {"a", "b", {1, 2}, 3}
print(equal(a, b))

edit: ordering function for tables isn’t necessarily consistent just using tostring, JSONEncode should work though. but really you can just compare both tables that way, so here’s a different equal function

function equal(a, b)
return HttpService:JSONEncode(order(a)) == HttpService:JSONEncode(order(b))
end

edit: fixed comparing tables directly and returning false after checking if the type is a table

3 Likes

Something like this?

local table1 = {{2, 1}, 2, 3}
local table2 = {{1, 2}, 2, 3}

local function CompareTables(t1, t2)
if #t1 ~= #t2 then
return false
end

for i = 1, #t1 do
local v1 = t1[i]
local v2 = t2[i]

if type(v1) == "table" and type(v2) == "table" then
return true
end

if v1 ~= v2 then
return false
end
end
return true
end

print(CompareTables(table1, table2))

I’ll give some examples of what I want just for future reference.

t1 = {1,2}
t2 = {2,1}
-- true
t1 = {"a","b",{1,2,{1,2}}}
t2 = {{{2,1},2,1},"b","a"}
--true
t1 = {"a","a","b"}
t2 = {"b","a"}
-- false
t1 = {1,{1,5}}
t2 = {1,5,1}
-- false
t1 = {2,1,{3,4}}
t2 = {{4,3},2,1}
--true
1 Like
function unpackMatrix(matrix)
local new = {}
for v, i in pairs(matrix) do
if type(i) == type({}) then
local otherTab = unpackMatrix(i)
for r, e in pairs(otherTab) do
table.insert(new, e)
end
else
table.insert(new, i)
end
end
return new
end

function compareUnsortedTables(tab1, tab2)
if #tab1 ~= #tab2 then
return false
end

tab1 = unpackMatrix(tab1)
tab2 = unpackMatrix(tab2)

local equal = true
for v, i in pairs(tab1) do
local isIn = false
for r, e in pairs(tab2) do
if e == i then
isIn = true
end
end

if not isIn then
equal = false
break
end
end
return equal
end

print(compareUnsortedTables(tab1, tab2))

Can you put the non JSONEncode version there as well so others can see?