I have this simple inventory system, and it has mixed keys and indexes.
I cannot send the table to the client with mixed indexes so I must create a table to send that inventory data (with a slot number) to the client.
I have a clickdetector that once I click it, it adds a new item to my inventory table using a modulescript.
Here is my AddItem event:
if #inventories[Player]["Items"] < 20 then -- Check if player has less than max items
if itemData.Slot == 0 then -- If it has a default slot (0) then position it automatically
for i,v in pairs(inventories[Player]["Items"]) do
v.Slot = i
end
table.insert(inventories[Player]["Items"],itemData)
else -- else if i give it a custom slot, then set it at that table spot.
table.insert(inventories[Player]["Items"],itemData.Slot,itemData)
end
local fakeTable = {} -- create the client table
for i,v in pairs(inventories[Player]["Items"]) do
print(v.Name,v.Slot)
table.insert(fakeTable,v) -- add all the item
end
reps.Events.InventoryInfo:FireClient(Player,fakeTable) -- fire that info
Now my issue is that my first clip / next doesn’t seem to register.
Once I click the clickdetector, it fires the slot 0 (even though tables should start with 1)
This gif shows that my first click gives me slot number 0, the first button should give me wands, and the second should give me swords. https://gyazo.com/cea5da05bd732de8be250fe1617017ae.gif
The issue is that I have to press twice on the sword/wand to get it to update.
The pairs function really only goes in order if the table is actually an array, as in the values have incremental numeric indexes starting from 1.
If you put something under the index 0 into your table, then not only you’re risking the # operator to give you the wrong value, but also pairs() iteration order for non-array tables is undefined.
If you didn’t intend to have something under the 0 index, you might want to look at where you define the inventories[Player]["Items"] table.
To clarify, this means {value1,value2,value3} will go in the respective order. If you have something like table[0] = blahblah, it will start at zero. Ignore that.
If I come across a situation like this, I can do the following:
for i,v in pairs(tableHere) do
print((i>0 and i) or 1) -- Returns one if it's not greater than zero.
end
That is not what this means! As stated in the post you quoted, the iteration order is not defined for this case, so the developer cannot rely on zero being the first index in the iteration.
The correct solution is to change the structure of the inventory data to separate out the array part and the dictionary part. This will help avoid these kinds of errors and incidentally make it easier to pass data to/from the client.