Table.find returning nil

I’m adding a report system to my announcement system. Just to be on the safe side, messages are logged and when the player reports a message the server verifies that the message was actually sent. Here’s the problem: it’s not working.

Here’s part a sample of the code that adds the index to the table (remember that this is only a sample of the whole thing)

local timeStamp = os.time() --Time player sent the message, will be useful if message is reported for data regarding the time the message was sent
table.insert(log,1,{["Message"] = broadcastFiltering,["UserId"] = player.UserId, ["Time"] = timeStamp})
log[40] = nil -- To prevent too much memory usage, this will limit the table to 40 indexes

Now here’s the search function that isn’t working ( the log variable has already been defined)

function searchLog(msg,userId,timeSent)
	local index = table.find(log,{["Message"] = msg,["UserId"] = userId,["Time"] = timeSent})
	if index ~= nil then
		return true
	else return false end
end

Lastly here’s the code that searches the log

report.OnServerEvent:Connect(function(player,msg,reason,timeSent,userId,additionalComment)
	local findMessage = searchLog(msg,userId,timeSent)
	repeat wait() until findMessage ~= nil
	if findMessage == true then
		print("Message Found")
	end
end)

It doesn’t print "Message found".

I did a test earlier to see if the indexes match up and they were the same here’s the output: (not current version of code)

 > Have a great day! 485407994 1643853850 - Data sent
 > Have a great day! 485407994 1643853850 - Log Data

I did the test using this code:

	print(msg,userId,timeSent.." - Data sent")
	print(log[1].Message,log[1].UserId,log[1].Time.." - Log Data")

Please ignore the fact that the player could be reporting not the most recent announcement this is just a test.

Why is it not working?

The most recent message will have the index of 1 in the log table.

you never re-run the function.

repeat wait() findMessage = searchLog(msg,userId,timeSent) until findMessage ~= nil

If that doesn’t work, try to print the table and see if it shows for that. You could also see if it just isn’t returning as the same table.

print({["Message"] = msg,["UserId"] = userId,["Time"] = timeSent} == log[1])
1 Like

I don’t think the function needs the to be re-run because the variable above runs it once so that line of code in simply waiting for the function to return something (true or false)

image
As you can see, tables have a sort of “id” to them, making them not equal to another table.You would have to go through the tables and check whether their contents are equal.

function searchLog(msg,userId,timeSent)
	local index = nil
	
	for i,v in pairs(log) do
		if table.unpack(v) == table.unpack({["Message"] = msg, ["UserId"] = userId, ["Time"] = timeSent}) then
			index = v
		end
	end
	
	if index ~= nil then
		return true
	else return false end
end

Edit: Sorry, sent unfinished script by accident when getting the screenshot.

1 Like

That is helpful. I knew that if you try to directly print a table you would just get an unhelpful memory address. However, I thought that you could compare two tables and they would be equal to each other. Though slightly inefficient, I’ll have to loop through the log to check if there are any matches.

As you correctly stated, table values are held/stored in addresses of memory such that when you attempt to print a table value its memory address at which it is currently situated is displayed in the console.

Unique table values will always be stored at different addresses in memory from one another, this means that you cannot equate tables with the primitive relational (comparison) operator “==”. Take the following for example.

local table1 = {1, 2, 3}
local table2 = {1, 2, 3}
print(table1 == table2) --false

Even though both tables appear to be the same the addresses in memory at which they are located differ meaning that they are considered unequal.

1 Like

Here’s a script I wrote for someone else facing a similar issue.

local EmptyTable1 = {}
local EmptyTable2 = {}

local function CompareTwoTablesRecursive(Table1, Table2)
	local Table1Keys, Table2Keys, Table1Values, Table2Values = {}, {}, {}, {}
	
	for Key, Value in pairs(Table1) do
		table.insert(Table1Keys, Key)
		table.insert(Table1Values, Value)
	end
	
	for Key, Value in pairs(Table2) do
		table.insert(Table2Keys, Key)
		table.insert(Table2Values, Value)
	end
	
	if #Table1Keys == #Table1Values then
		local Length = (#Table1Keys + #Table2Keys)/2
		for Index = 1, Length do
			local Key1, Key2, Value1, Value2 = Table1Keys[Index], Table2Keys[Index], Table1Values[Index], Table2Values[Index]
			
			if type(Key1) == "table" and type(Key2) == "table" then
				if not CompareTwoTablesRecursive(Key1, Key2) then
					return false
				end
			elseif Key1 ~= Key2 then
				return false
			end
			
			if type(Value1) == "table" and type(Value2) == "table" then
				if not CompareTwoTablesRecursive(Value1, Value2) then
					return false
				end
			elseif Value1 ~= Value2 then
				return false
			end
		end
		return true
	else
		return false
	end
end

print(CompareTwoTablesRecursive(EmptyTable1, EmptyTable2)) --true
1 Like

Lua/all programming languages automatically wait for a function to finish running when using it normally (aka calling it)

local function SomeFunction()
    task.wait(10)
end

print("Go!")
SomeFunction()
print("Done!") --Only prints after 10 seconds, as SomeFunction waits for 10 seconds
1 Like