Greetings,
As a Roblox developer, it is currently impossible to slice tables and use negative indexing natively. Currently, you’d have to develop some exotic function or use metamethods to mimick those methods in a strange way. My ListLib module uses __call
to slice tables, which is syntactically strange, not to mention the function has to be user-defined.
Negative indexing starts with the last element, as opposed to positive indexing that starts with the first:
local array = {1, 2, 3, 4, 5, 6, 7}
print(array[1]) --1
print(array[-1]) --7
print(array[-2]) --6
Currently, negative indexing does not error, just returns nil, so this should definitely become a feature!
Slicing can be used to get chunks of the table via start, end, and step indices, which can be negative:
print(array[2:4]) -- {2, 3, 4}
print(array[2:-2]) -- {2, 3, 4, 5, 6}
-- missing index number defaults to start/end, depending on which is omitted
print(array[4:]) -- {4, 5, 6, 7}
print(array[:3]) -- {1, 2, 3}
-- with step (defaults to 1)
print(array[3::2]) -- {3, 5, 7}
print(array[::3]) -- {1, 4, 7}
-- negative steps go in reverse
print(array[::-1]) -- {7, 6, 5, 4, 3, 2, 1}
Of course, these integers can be variables.
Use Cases
Snip-Snip
There are many times where I need to snip of the first or last element of an array. Currently, it’d be an inconvenient two-line process:
local snipped = {table.unpack(array)} -- make a copy
table.remove(snipped, 1) -- remove first element
But then what if I want to snip off multiple elements? table.remove
does not allow multiple indices to be given, which would result in either a for loop or multi-lined removal.
Last Element
There are also many instances where I want to get the last (or second to last, etc.) element of an array, which the only way right now is array[#array]
which lengthens with the variable name. Of course, array[-1]
is undeniably shorter.
Now, it’d be great to have the slicing syntax be with
:
similar to Python, but in any case where it may clash with Luau type checking (such as the “as”::
operator), a new function can be added to thetable
library:
table.slice(array: table, start: int = 1, end: int = -1, step: int = 1) -> table
If these were added, it’d improve my development experience because I’d be able to swiftly access elements as fit for the circumstance and snip tables in a single line. The table
library, I find, is quite limited such as not allowing multiple indices to remove when removing, so any workarounds would be inconvenient. With Luau branching off from the original Lua 5.1 pipeline, it’s syntax has retained most aspects of traditional Lua, but with certain additions such type checking syntax and compound operations. Therefore, slicing and negative indexing would add to this collection of convenient features.
Thank you.