How to check if two tables match?

I know you can just loop through the table, but I feel like that might be inefficient compared to different ways, and I want that to be a last ditch effort.
I feel like it could be as simple as this:

if table1 == table2 then
    print("They match!")
end

does anyone have a good method of doing this?

The way I’d do it is convert them to JSON and then compare.

t1 = {
    test = {5, 1, 23},
    9, 100, 'thing'
}

t2 = {
    test = {5, 1, 23},
    9, 100, 'thing'
}

local HttpService = game:GetService('HttpService')
print(HttpService:JSONEncode(t1) == HttpService:JSONEncode(t2)) --> true

The thing with the string comparing is that you might consider a table matching for your own purposes but they aren’t. It depends on what you need but I’ve placed an example below because I’m not too sure how to explain.
Example this one: t1: {1, 3, 5} ; t2: {1, 5, 3}

Is there a way to do this without http services? it’s fine if there isn’t, but just asking.

Yes, but you would need to do a Recursive Search through the Table.

1 Like

Yes there is. Are you looking for a deep or shallow compare?


local function DictionaryGetn(d: {[any]: any}): number
	local count = 0

	for key, value in pairs(d) do
		count += 1
	end

	return count
end

local function nilparam<a>(param: a?, default: a): a
	if param == nil then
		return default
	else
		return param
	end
end

local function IsDictionary(t: table): boolean
	if type(t) ~= "table" then
	error(`Field 't' expected table, got {typeof(t)}.`)
		return false
	end

	return (t[1] == nil) --returns a boolean
end

local function TableToString(t: {[any]: any}, sep: string?, i: number?, j: number?): string?
	if DictionaryGetn(t) == 0 then
		return "{}"
	end

	local stringToConvert = "{"

	sep = nilparam(sep, ", ")
	i = nilparam(i, 1)
	j = nilparam(j, #t)

	if not IsDictionary(t) then
		if i <= 0 or i > #t then
		error(`Field 'i' must be greater than 0 and less than or equal to {#t}.`)
			return
		end

		if j <= 0 or j > #t then
			error(`Field 'j' must be greater than 0 and less than or equal to {#t}.`)
			return
		end
	end

	if IsDictionary(t) then
		local total = DictionaryGetn(t)
		local current = 0

		for key, value in t do
			current += 1
			if type(value) == "string" then
				value = `"{value}"`
			end
			if type(value) == "table" then
				value = TableToString(value, sep)
			end
			if current == total then
				stringToConvert = `{stringToConvert}["{key}"] = {value}}`
			else
				stringToConvert = `{stringToConvert}["{key}"] = {value}{sep}`
			end
		end

		return stringToConvert
	end

	for index = i :: number, j :: number do
		local value = t[index]
		if type(value) == "string" then
			value = `"{value}"`
		end
		if type(value) == "table" then
			value = TableToString(value, sep)
		end
		if index == j then
			stringToConvert = `{stringToConvert}[{index}] = {value}}`
		else
			stringToConvert = `{stringToConvert}[{index}] = {value}{sep}`
		end
	end

	return stringToConvert
end

Not the best, but it works great!

return (t[1] == nil) --returns a boolean
1 Like

It’s actually

return not t[1]

because false would return true, but false ~= nil so it would still return false with your example

1 Like

yep, but one of them is more specific than the other, not value would do it if its false or nil, which == nil does it if its nil, but both can work for the same purpose.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.