Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How can I view the contents of this table?

I have a datastore that saves a table and when I print the table result when the player loads it prints this: table: 19918444 and it is not a table as far as I can see. Could someone help me with this? If you need the script I will post it. Also the for loop that is supposed to loop through the table doesnt work. Hope you guys can help me. Thanks!

Edit 1. saving part:

game.Players.PlayerRemoving:Connect(function(plr)
	
	if plr.CanSave.Value then
		
		local specialKey = "User_"..plr.UserId
		local plrName = plr.Name
		local plrInfo = game.ServerStorage:FindFirstChild(plrName):WaitForChild("PlayerInfo")
		
		if plrInfo.OwnsTycoon.Value then
			
			local tycoonName = plrInfo.OwnedTycoon.Value
			local tycoon = game.Workspace.Tycoons:FindFirstChild(tycoonName)
			local moneyToSave = plrInfo.Money.Value
			local buildLevelToSave = plrInfo.BuildLevel.Value
			local purchasedItemsTable = getTableForDataStore(tycoon, plrInfo)
			local mainTableToSave = {moneyToSave, buildLevelToSave, purchasedItemsTable}
				
				
			
			local success, message = pcall(function()
				
				mainDataStore:SetAsync(specialKey, mainTableToSave)
				
			end)
		end
	end
end

loading part:

script.Parent.Touched:Connect(function(hit)
	
	if script.Parent.CanCollide then
		if hit.Parent:FindFirstChild("Humanoid") then
			if hit.Parent.Humanoid.Health > 0 then
	
			local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
			local plrName = plr.Name
			local plrInfo = game.ServerStorage:FindFirstChild(plrName):WaitForChild("PlayerInfo")
			local specialKey = "User_"..plr.UserId
			local tycoon = script.Parent.Parent.Parent.Parent
			local tycoonName = tycoon.Name
			local mainDataTable 
			local serverTycoon = game.ServerStorage:FindFirstChild("Model"..tycoon.Color.Value.."Tycoon")
		
			if not plrInfo.OwnsTycoon.Value then
				if not tycoon.IsOwned.Value then
	
						tycoon.IsOwned.Value = true
						tycoon.Owner.Value = plrName
						plrInfo.OwnedTycoon.Value = tycoon.Name
						plrInfo.OwnsTycoon.Value = true
						
						script.Parent.Transparency = 1
						script.Parent.CanCollide = false
	
						local success, message = pcall(function()
							 
							mainDataTable = mainDataStore:GetAsync(specialKey)
	
						end)
	
						if success then
				
							print("Player Data Loaded Successfully")
							
							plrInfo.Money.Value = mainDataTable[1] or 0
							plrInfo.BuildLevel.Value = mainDataTable[2] or 1
							
							local buildLevel = plrInfo.BuildLevel.Value
							local baseplate = findBaseplate(buildLevel, serverTycoon)
							local baseplateName = baseplate.Name
							local tycoonBaseplate = tycoon:FindFirstChild("Baseplates"):WaitForChild(baseplateName)
							local serverBaseplate = serverTycoon:WaitForChild(baseplateName)
							local copy = baseplate.BaseplateEssentials:Clone()
							copy.Parent = tycoon.Baseplates:FindFirstChild(baseplateName)
							print(mainDataTable[3])

and the print at the end is what gives the output I set Please help!

1 comment

0

post code pl0x0rz

2 answers

✓ Accepted answer

To expand on iiiGodRoblox's answer

Arrays and dictionaries usually cannot be printed in a human readable format if just printed to console or tostringed.

tostring(table t) will return some weird string that we know is table: some hexadecimal number, but that doesn't really give a lot of information about the table, sure it's nice that we can print it but it's not really too useful to use right now.

For us to actually view and inspect an array or dictionary, we can either use some that returns the table as a string or __tostring metamethod.


How To Implement

If you're bored of reading and just want an easy solution, you can use

local function DumpTable(t)
	local str = {}
	for Index, Value in pairs(t) do
		table.insert(str, tostring(Value))
	end
	return "{" .. table.concat(str, ", ") .. "}"
end

It's not necessarily the best solution, but it works and it's simple enough to understand at a glance.

If you're curious for more information, you can keep on reading.

There's an obvious problem with the code above, it doesn't support nested tables; let's say we have a table structured as such

{
	Hello = "World",
	Programmed = {
		"To"
		"Work"
	},
	And = {
		Not = "to",
		Feel = true
	}
}

What our code above might output would be something along the lines of {World, table: 0xBAADF00D, table: 0xFFFFFF} Yeah, it prints it out but now we're back to our original problem, it's printing table: hex again.

What we can do is have some kind of recursive implementation that checks the type of Value and if it's a table, then dump that table

The code may fall something along the lines like

local function DumpTable(t)
	local str = {}
	for Index, Value in pairs(t) do
		if type(Value) == "table" then
			table.insert(str, DumpTable(Value))
		else
			table.insert(str, tostring(Value))
		end
	end
	return "{" .. table.concat(str, ", ") .. "}"
end

If we inspect the code, we can see that it'll handle tables inside tables and tables inside those tables correctly.


Self referential tables

This should be enough for most people, but what if you're really eccentric and have something like

local a = {}
local b = {a}
a[1] = a

Now, at first, this may seem to work, its just tables inside tables but now this presents another problem: self-referential tables

This is what our little function will do

DumpTable(a)
	-> __index(a, 1) = b
	-> DumpTable(b)
		-> __index(b, 1) = a
		-> DumpTable(a)
			-> __index(a, 1) = b
			-> DumpTable(b)
			... forever

Now that's a problem, it just keeps on dumping a and b! This will go on infinitely and will cause a stack overflow which isn't good for both us and the computer.

What we can do to solve this is keep track of the tables that we already turned into strings, if it hasn't then do whatever we usually do, else just return tostring(t)

local function DumpTable(t, Printed)
	Printed = Printed or {}
	if Printed[t] then
		return tostring(t) --this is where we stop self-referential tables
	end
	Printed[t] = true
	local str = {}
	for Index, Value in pairs(t) do
		if type(Value) == "table" then
			table.insert(str, DumpTable(Value, Printed))
		else
			table.insert(str, tostring(Value))
		end
	end
	return "{" .. table.concat(str, ", ") .. "}"
end

Now, this is what our function will do with the table a and b problem:

DumpTable(a, {})
	-> __index(a, 1) = b
	-> DumpTable(b, Printed)
		->__index(b, 1) = a
		-> DumpTable(a, Printed)
			-> a is in Printed, return tostring(a)
		-> return "{" .. tostring(a) .. "}"
	->return "{{" .. tostring(a) .. "}}

DumpTable(a) == "{{" .. tostring(a) .. "}}"

This may seem not that useful but that's just because it isn't necessarily the best example; however, it clearly illustrates that, yes, it can handle self-referential tables while not having a stroke and dying.

Of course, this doesn't solve all our problems, it shows strings as String rather than "String", which isn't optimal and while yes it works with both arrays and dictionaries, dictionary support isn't exactly the best as it doesn't include the index. Using what you learned in this answer, try extending our code to work and solve these little problems.

If you want to use existing code to inspect tables, you can use Kikito's inspect.lua or my own table.FormatValue

1 comment

0

Thank you so much!

Well you could see the content of the table by using a for loop like the following

local tab = {'a','b','c','d',...}
for i,v in pairs(tab) do
	print(i,v)
end

This discussion is preserved as it was. New answers, comments, and votes are closed.