Why does this print nil?

So, I have a table (using for saving the player’s inventory)
and I use this code to insert tools inside a table to later save.

table.insert(Tools, tool.Name)

Now, don’t get me wrong and all, this WORKS.
However, I tried

print(Tools[tool.Name])

Why does this print ‘nil’?
image
If you could help me, I appreciate it. I’m trying to add more objects by doing

Tools[tool.Name] = {["Example1"] = "1", ["Example2"] = "2", ["Etc"] = "3"}

But Tools[tool.Name] is nil, and I don’t know the reason for that, since when I do

print(unpack(Tools))

It does print.
image

I am using { }.

What kind of table are you using? {} or table.pack()?

EDIT: Okay I got nothing then.

1 Like

Tools[Key] not Table[Value]

the name of the tool isn’t a key in that scenario

It’s printing nil because Tools isn’t a dictionary but a table, and you are attempting to index the table by the string tool.Name, which isn’t an integer, and therefore returns nil.

So should I do something like this?

Tools[tool.Name] = {[""] = "", [""] = ""}

It appears you want a dictionary rather than a table, so when you want to insert a value into the dictionary, use

table[index] = value
-- ex: Tools[tool.Name] = true

instead of

table.insert(Tools, tool.Name)

If you were to run the following code below in your script,

Tools[tool.Name] = true
print(Tools[tool.Name])

the output would be

true

What you were doing before is inserting a value into a table using the table.insert method, but then trying to print a specific value in a table by the value, rather than the index.

This would work, however,
I want to get the key name too. When attempting to load the tools, I’m looping through a table which the datastore saved, so, if i were to use a for loop then it would print the value, and not the index name (which is what i do want it to do)
I want to find both the tool name and bool. Example:

for i, Tool in pairs(Table) do
       print(Tool[1]) -- Tool Name
       print(Tool[2]) -- True/False
end

I think what you’re having trouble with is the definition of a “Dictionary” versus and “Indexed Array.”

Indexed Arrays work like this:

t = {}
t[1] = "Hello "
t[2] = "World"
table.insert(t,"!") --table.insert is generally used to add things to the end of an indexed array like this one
print(t[1],t[2],t[3]) --in this case t[3] is set to "!"

Dictionaries work like this:

t = {}
t[1] = "Frogs " -- currently this is still an indexed array
t["Two"] = "are " -- you now assigned a non-integer value to the table so it's now a dictionary
t[3] = "really cool." -- even though you assign t[3] the same as t[1] it's still a dictionary forever now.

The take away here is that it’s very easy to use and design functions that handle indexed arrays correctly but break when you throw a dictionary in or vice versa. When you used “table.insert” it created an indexed array, not a dictionary. So you have to reference it only by indices (aka t[1],t[2],etc…)

What it sounds like you want is dictionary behaviour, which means instead of using “table.insert” you would do something like this:

tools = {}
crescent_wrench = {name="crescent_wrench"}
tools["crescent_wrench"] = crescent_wrench
print(tools[crescent_wrench.name])

Edit:
In the case of needing a table to function as both, you save it as an index array first and either use a lookup function or a lookup table to find the data you need.

a function would loop over the indices of the table and check each k/v pair do something like:

function find_thing(table,thing_name)
    foreach key,value in pairs(table) do
        if value.name = thing_name then
            return value -- or you can return the key and use table[key] to access the value depends what you need
        end
    end

end

2 Likes

table.insert is used for tables/lists, not dictionaries! Since you are use table[string], you need to manually insert the value with table[key] = value instead of table.insert

1 Like