Not getting first empty spot in table

Inventory

Inventory = {
			[1] = {Type = 'Weapon', Name = 'Wooden Sword', Durability = 30},
			[2] = {Type = 'Tool', Name = 'Wooden Axe', Durability = 30},
			[3] = {},
			[4] = {},
			[5] = {},
			[6] = {},
			[7] = {},
			[8] = {},
			[9] = {},
		},

Adding item to inventory (if item does not already exist)

for i, v in pairs(User.Inventory) do
	if v.Type == nil then
		User.Inventory[i] = {Type = 'Material', Name = item, Quantity = 1}
		InventoryManager:Update(player)
		
		return true
	end
end

No errors, problem lies in the fact that it’s putting the item in slot 7 and not slot 3. I want it to basically find the first empty slot and put it there

1 Like

Your issue may be that {} == nil resolves to false, i.e. an empty table is not classified as a nil object. Not sure why it’s putting it in slot 7 though…
Try replacing if v.Type == nil then with if v == {} then and see if that works

1 Like

Doesn’t work at all now

v.Type == {} wouldn’t make sense.

I’ll try v == {}

That was a slip-up on my part - you’re correct, v == {} is the logic you want. I’ve edited my original reply to reflect this

Just tried v == {} and still doesn’t work. Added a print afterwards to make sure it was that line that’s stopping and ye it is

i don’t think it will ever equal nil, because their values are all tables if that makes sense, maybe check if #v = 0 instead

Still resulted in the items being put in slot 7, not 3

hmm… try using ipairs instead of pairs

Assuming that all inventory objects have a “Type”, the check v.Type == nil should return the empty slot

That just replaced whatever item was in slot 1

if you take null and put it instead of nil try to do it

I can of course be mistaken, but suddenly it works out

What???

null is a synonym for nil.

Use ipairs here instead of pairs.

Already tried…

Ah I see what’s happening. You’re setting Inventory[i] which isn’t necessarily the same thing as v.

An easy fix here would be to initialize your Inventory table without the keys like so:

Inventory = {
	{Type = 'Weapon', Name = 'Wooden Sword', Durability = 30},
	{Type = 'Tool', Name = 'Wooden Axe', Durability = 30},
	{},
	{},
	{},
	{},
	{},
	{},
	{},
}

With this pairs should work fine. ipairs uses an iterator instead of an index which is why the value you’re still setting the wrong index in your table. It’s basically because your table isn’t sorted the way you think it is.

Pretty sure I deliberately set up using keys, as my inventory UI uses a number system of 1-9, and so they need to use the key to get the right spot

Using keys 1-9 is pointless. Those values are automatically assigned in an array structured table anyway. The only difference is that your 1-9 isn’t the same as the array’s 1-9 once its sorted automatically. You don’t want to go about looking up keys in a table with numbers because Lua is going to think they’re array indices.

Letting the values be assigned by the order they’re entered into the table should be fine, even for your UI.

Can’t say the same thing for saving and loading that data though. You probably want to come up with a better key name… even something as simple as making the numbers a string would be easier to reference as a table key lookup, just keep in mind that you’ll need to tostring the index “number” you’re trying to look up.

Regarding the earlier replies, a table is only ever equal to itself, i.e.

t={}
t == t

or

a = {}
b = a
a == b

is true, but

{} == {}

or

{foo=1}=={foo=1}

Are both false.

Instead of using in pairs, which does not have a guaranteed order and will not always go 1,2,3,4 etc., use
for i=1, #User.Inventory do
instead, or use ipairs which will also work in order for an array without missing keys.

Also, as previously mentioned you’ve done this:

t = {
 [1] = foo
 [2] = bar
}

This is not what you want here.
Use either

t ={foo, bar}

or

t = {}
t[1] = foo
t[2] = bar
2 Likes