Why do some people use table[index + 1] instead of table.insert?

Ohh, so it will keep returning 0 if the integers in the middle are nil. I get it now!

1 Like

Well, that’s good to know! Thanks a lot!

To answer your original question: t[#t + 1] is an insertion method used outside of Roblox, but also in some old Roblox code. This practice is now considered bad, and you should always use table.insert if you want to insert new values into an array.

1 Like

Yes. I was referring to this variant (which also explicitly mentions ‘array’):
void table.insert(array t, number pos, Variant value)

From an indexing standpoint, an array can be thought of as a sequentially numbered dict. It can’t have gaps and prob needs to start at 1, but a table that’s set up that way can be treated as either an array or a dict.

Edit: (Will edit this rather than add another post)

The t[#t+1] = newVal form adds an entry to the end of an array and is a technique used in other languages where arrays and dictionaries are completely different structures (so no ambiguity, and arrays are guaranteed to be well-formed). This approach can lead to confusion in Lua since it adds a new array entry using the Lua dict[key] = newVal approach, but the values in table t are assumed to be, and must be, stored as an array for it to work (the #t doesn’t work correctly if the table isn’t an array). If you start removing values in your array with the similarly structured t[n] = nil assignment, you can break the array.

Obv we’re using t[index|key] = updateVal to make changes to existing entries either way, but using the t[key] = newVal and t[key] = nil approach when you need to add/rem a dict entry and the table.insert(t, newVal) and table.remove(t, remIndex) when you need to add/rem an array entry is best practice (as Pyseph notes) since it avoids ambiguity, and the later table methods ensure that your arrays stay well-formed.

1 Like

I’m not going to be choosing any posts as a solution, because all the posts has explained a lot! (Anybody who sees this post sometime later, should just check this full thread, so you know more!)

Thanks a lot everybody!

Open for extra information

So, mainly the full post explained that

table[#table + 1]

is a bad an old practice, which you can achieve using table.insert() which Astr0 showed in reply before this one!

If you define a key then it becomes a dictionary but the [] can be used for both arrays and dictionaries. It’s used to set and read the data at that key or index.

table.insert() does not work on dictionaries, I believe you may be confused.

I’m not saying it does, I’m saying it dosent.

[1] = "notfunnymemeamogus"

With that table.insert method

This post was very unclear.

local dictionarytable = {
[1] = "good time to use their method"
}

and this isn’t an example of a dictionary.

table.insert is a function call.
The roblox script thing looks for table.insert value in the global memory area and then calls it.

[#table + 1] is much faster

There’s nothing such as dictionaries in luau, they are tables with non-numeric indexes. So no, this is incorrect, table.insert() will actually work on “dictionaries” since they can have both numeric and non-numeric indexes at the same time.

Also the difference between table.insert() and table[#table + 1] is that with table.insert(), you’ll always start from the last numeric index (or 0 if the table has none) and with table[#table + 1] you’ll always start from the length of the table, not the last numeric index.

They are exactly the same.
image

Code
local insert_table = {}
local index_table = {}

local insert_start = os.clock()
table.insert(insert_table, "a")
print("table.insert took: " .. os.clock() - insert_start)

local index_start = os.clock()
index_table[#index_table + 1] = "a"
print("t[#t + 1] took: " .. os.clock() - index_start)
1 Like

Not to discredit those results, but typically comparing the time taken to execute calls is done over millions of iterations and not just one-time calls.

Well it’ll probably still remain very close since both are O(1) and are precisely the same

w/ 10000 iterations
image
(I’m actually surprised that table.insert is a bit faster)

1 Like

I got consistent results on my end doing 5 million iterations.

table.insert took: 0.9502674000000297
t[#t + 1] took: 1.0756107000001975

But like you said, the difference isn’t really significant at all on a per-call basis. Even across 5 millions iterations. table.insert is faster by just ~120ms.

This is very interesting because usually function calls are slower, but ig table.insert doesn’t have to measure the length of the table

This use to be true, but I recall either Luau or Lua was updated such that they now have nearly identical performance.

The only potential difference now is from getting the table global, which is pretty negligible.


Per the Luau documentation:

When appending elements to tables, it’s recommended to use table.insert (which is the fastest method to append an element to a table if the table size is not known). In cases when a table is filled sequentially, however, it can be more efficient to use a known index for insertion - together with preallocating tables using table.create this can result in much faster code, for example this is the fastest way to build a table of squares:

local t = table.create(N)

for i=1,N do
	t[i] = i * i
end
1 Like

Okay, well, saying table.insert(t, v) is the exact same saying t[index + 1] = v, the thing that could change, is when you are using the 0 value, which recognized by the luau parser not as part of, we can call it “Luau array”.
0 in other languages like js or java is in the array itself, but ipairs, can’t read it, instead pairs can.
About the efficiency well, I don’t think there is much of a change, as table.insert(t,v) must use the same criteria as t[index + 1] = v.
Same for table.remove().

i dont use ipairs. Using pairs makes code run slower even if its negligible

If you have string, boolean, or any types different than a number then you cannot use ipairs and you have to use pairs.