Why is table.insert acting this way?

Posted this on Reddit, but haven’t had much help there. So here it is:

local tab = {
    [1] = "WOW",
    [2] = "Meow",
    [3] = "I am 3",
    [7] = "SOFA"
}
print(#tab) -- Prints 3, since there is no +1 after [3].
print(tab)

--[[table.insert(tab, "Kitty")
table.insert(tab, "Kitties")
table.insert(tab, "KITTIES")--]]
tab[#tab+1] = "Kitty"
tab[#tab+1] = "Kitties"
tab[#tab+1] = "KITTIES"

print(#tab) -- Prints 8, [6] is being set as nil, and "KITTIES" went to index [8].
print(tab)

The complication is this:
Why is [6] becoming nil when SOFA is at [7]?
Why is [6] skipped when SOFA is at [8]?
Normal behavior is seen with other values. So why are 7 and 8 so special?

The problem happens whenever I attempt to insert a new value to my array.
I have tested very little, but I noticed that [6] becomes nil when a value is added to [5]. Placing wait() between added values does nothing.
Is this just normal behavior? Or is this truly uncommon.
I can think of ways to go around the problem, but I’d still like to know why this is happening.

Thank you :slight_smile:
have a gewd day.

1 Like

A stupid “feature” from the luau language it self where it tries to predict an array. One way you could avoid this is by caching the table length

local tab = {
    [1] = "WOW",
    [2] = "Meow",
    [3] = "I am 3",
    [7] = "SOFA"
}
print(#tab)
print(tab)

local TableLength = #tab
tab[TableLength + 1] = "Kitty"
tab[TableLength + 2] = "Kitties"
tab[TableLength + 3] = "KITTIES"

print(#tab) 
print(tab)

This is a option but there is a better way.

local function GetTableLength(Table:{})
    local z = 0
    for i,v in pairs(Table) do
        z +=1
    end
    return z
end

Why do you need the indexes like that anyways?

Just thinking of possible cases. Found this while testing stuff. Wanted to know why it happens.

I see. Thank you very much for the response! By the way, can you (if possible) link me to that section of luau? I’d love to know more about these types of… “features”. If you don’t remember the specific section, mind dm me the main page? Thank you ^ ^

I see the logic behind this. Haven’t tested your code, but would your function read nils? I imagine not, but I noticed the ‘#’ when reading my table did catch the nil indexes as - what I would call it - false positives. I will still test this when I have the time. Thank you :slight_smile:

No, pairs/ipairs ignores nil table values and will skip over them not accounting to the table length.

I see, that’s quite interesting. Thank you for the clarification :slight_smile:
So, since pairs and ipairs skip nils, there’s a chance that a table could contain nil values, and you wouldn’t know? Would it matter that you don’t know they are there?

By the way, what does the Table:{} parameter represent?
Is it a way to only accept a table and nothing else? Or is it an easy way to “mark” the type for the reader/scripter.