I’ve got a loop that goes through a player’s inventory and adds the name of their item to the table, with the index of that element being the item’s class (an IntValue, e.g. 1 or 3).
Let’s say I have 1 gun equipped with a class of 1, and another equipped with a class of 3. When I loop through these and put them on a table, for some reason a new element with a value of nil and index of 2 gets created to fill in the gap. How do I stop this?
local tools = {}
if #plr.Backpack:GetChildren() > 0 then
for i, v in plr.Backpack:GetChildren() do
if v:IsA("Tool") and v:FindFirstChild("CLASS") then
local hotkeyAssigned = tonumber(v.CLASS.Value)
if tools[hotkeyAssigned] then
repeat hotkeyAssigned += 1 until not tools[hotkeyAssigned]
end
tools[hotkeyAssigned] = v.Name
end
end
end
print(#tools) -- prints 3 even though there's 2 tools
The # doesn’t give you the number of non nil keys, it gives the highest numerical index with a non nil value. (It’s shorthand for table.maxn(t))
So if the only issue is the print(#t) seems off, you don’t have a problem.
You could use stringified number keys to give a dictionary, but then you need to count the keys in a separate function. But this is the same solution as counting non nil values in an array with ‘gaps’.
Print() uses an iterator to go through all the elements in a table, so arrays with gaps can be unpredictable in what they will print, ‘filling in’ missing keys and completely missing out portions of tables if there consecutive gaps.
I would recommend using string key indexes or not leaving any gaps tbh.
I think it has been reported as a bug before, but currently the docs recommend to not leave gaps in array like tables. I think the type of table (array or dictionary) can be dynamic depending on how the engine interprets it in a given context, or how it is stored in memory or something.