tableLuaLuauLuwu

The table library creates and copies tables, inserts and removes array elements, searches and sorts arrays, joins them into strings and freezes tables against changes.

Input
const players = { "nyla", "ada", "lin" }
table.insert(players, "bo")
table.sort(players)
print(table.concat(players, ", "))
print(table.find(players, "lin"))

const roster = table.freeze(table.clone(players))
print(table.isfrozen(roster))
Output
ada, bo, lin, nyla
3
true

See Tables

Summary

Creating and copying

table.createLuau
Creates an array with room for a number of items
table.cloneLuau
Returns a shallow copy of a table
table.moveLuau
Copies a range of items into another table or within the same one

Adding and removing

table.insertLua
Appends an item or inserts it at an index
table.removeLua
Removes the item at an index or the last item and returns it
table.dropLuwuflagged
Removes the items equal to a value and returns how many it removed
table.clearLuau
Removes every key but keeps the allocated memory

Searching and sorting

table.findLuau
Returns the index of the first item equal to a value
table.sortLua
Sorts an array in place
table.maxnLua
Returns the largest positive numeric key in a table

Packing and joining

table.packLuau
Returns an array of its arguments with their count in n
table.unpackLuau
Returns a range of items as separate values
table.concatLua
Joins a range of items into one string with a separator

Freezing

table.freezeLuau
Freezes a table so its keys and metatable can't change
table.isfrozenLuau
Checks whether a table is frozen

Deprecated

table.getnLuaLuaudeprecated
Returns the length of an array
table.foreachLuaLuaudeprecated
Calls a function with every key and value of a table
table.foreachiLuaLuaudeprecated
Calls a function with every index and item of an array in order

Creating and copying

table.createLuau

function table.create<V>(count: number, value: V?): { V }

Creates an array with room for count items. When value is given, every index from 1 to count is set to it. Without it the array is empty and has its space reserved for filling later.

Input
const scores = table.create(4, 0)
print(table.concat(scores, ", "))
Output
0, 0, 0, 0

A negative count is an error.

table.cloneLuau

function table.clone<T>(t: T): T

Returns a shallow copy of the table with the same keys, values and metatable. The copy is never frozen, even when t is. Nested tables are shared between the two.

Input
const original = { tags = { "new" }, count = 1 }
const copy = table.clone(original)
copy.count = 2
table.insert(copy.tags, "sale")
print(original.count)
print(#original.tags)
Output
1
2

A table whose metatable has a __metatable field can't be cloned.

table.moveLuau

function table.move<V>(src: { V }, a: number, b: number, t: number, dst: { V }?): { V }

Copies the items at indices a to b of src into dst starting at index t and returns dst. Without dst the items are copied within src. Overlapping ranges in the same table are copied correctly.

It reads src and writes dst directly without calling __index or __newindex.

Input
const first = { 1, 2, 3 }
const second = { 4, 5 }
const both = table.move(second, 1, #second, #first + 1, first)
print(table.concat(both, ", "))
Output
1, 2, 3, 4, 5

An empty range (b less than a) copies nothing. Moving into a frozen table is an error.

Adding and removing

table.insertLua

function table.insert<V>(t: { V }, value: V)
function table.insert<V>(t: { V }, index: number, value: V)

With two arguments, appends value to the end of the array like t[#t + 1] = value. With three, inserts it at index and moves the items from there to the end up by one.

It writes to t directly without calling __newindex.

Input
const queue = { "Grace", "Alan" }
table.insert(queue, "Linus")
table.insert(queue, 1, "Ada")
print(table.concat(queue, ", "))
Output
Ada, Grace, Alan, Linus

An index outside 1 to #t moves nothing and sets t[index] directly. Calling it with any other number of arguments is an error.

table.removeLua

function table.remove<V>(t: { V }, index: number?): V?

Removes the item at index and returns it. The items after it move down by one and the array keeps no hole. Without index or when it's nil, the last item is removed. An index outside 1 to #t removes nothing and returns nothing.

It reads and writes t directly without calling __index or __newindex.

Input
const queue = { "Ada", "Grace", "Alan" }
print(table.remove(queue, 1))
print(table.remove(queue))
print(table.concat(queue, ", "))
Output
Ada
Alan
Grace

Since a nil index removes the last item, table.remove(t, table.find(t, value)) removes the wrong item when the value is missing. Luwu warns about an index that might be nil. Use table.drop to remove items by value.

table.dropLuwuflagged

function table.drop<V>(t: { V }, value: V, count: number?): number

Removes the items equal to value and returns how many it removed. By default every match is removed. When count is given, only the first count matches are. The items after a removed one move down and the array keeps no holes. A missing value removes nothing and returns 0.

It reads and writes t directly without calling __index or __newindex. Comparisons use == and respect __eq.

Input
const queue = { "retry", "done", "retry", "retry" }
print(table.drop(queue, "retry", 2))
print(table.drop(queue, "skip"))
print(table.concat(queue, ", "))
Output
2
0
done, retry

A frozen table is an error, and so is a count of zero or less. The Library Extensions guide page explains the bug it replaces.

table.clearLuau

function table.clear(t: {})

Removes every key from the table but keeps the memory it has allocated. Filling the table again up to the same size doesn't reallocate. Clearing a frozen table is an error.

Searching and sorting

table.findLuau

function table.find<V>(haystack: { V }, needle: V, init: number?): number?

Returns the index of the first item equal to needle or nil if there's none. The search starts at init (1 by default) and stops at the first nil. An init below 1 is an error.

It reads haystack directly without calling __index. Comparisons use == and respect __eq.

Input
const fruits = { "apple", "kiwi", "pear", "kiwi" }
print(table.find(fruits, "kiwi"))
print(table.find(fruits, "kiwi", 3))
print(table.find(fruits, "plum"))
Output
2
4
nil

table.sortLua

function table.sort<V>(t: { V }, comp: ((V, V) -> boolean)?)

Sorts the array in place. Without comp items are sorted in ascending order with <. With it, comp(a, b) returns true when a should come before b.

It reads and writes t directly without calling __index or __newindex.

Input
const names = { "Grace", "Ada", "Alan" }
table.sort(names)
print(table.concat(names, ", "))

const scores = { 40, 95, 70 }
table.sort(scores, function(a, b)
    return a > b
end)
print(table.concat(scores, ", "))
Output
Ada, Alan, Grace
95, 70, 40

table.maxnLua

function table.maxn<V>(t: { V }): number

Returns the largest positive numeric key in the table, or 0 if there's none. Unlike # it looks at every key and isn't confused by holes.

Input
const sparse = { [1] = "a", [2] = "b", [10] = "j" }
print(table.maxn(sparse))
Output
10

Packing and joining

table.packLuau

function table.pack<V>(...: V): { n: number, [number]: V }

Returns an array of its arguments with the field n set to how many there were. Unlike #, n counts nil arguments.

Input
const packed = table.pack("a", nil, "c")
print(packed.n)
Output
3

table.unpackLuau

function table.unpack<V>(list: { V }, i: number?, j: number?): ...V

Returns the items from index i to j as separate values. i defaults to 1 and j to #list. The global unpack is the same function.

It reads list directly without calling __index.

Input
const point = { 3, 4, 5 }
const x, y = table.unpack(point, 1, 2)
print(x + y)
print(math.max(table.unpack(point)))
Output
7
5

Unpacking more values than fit on the stack is an error.

table.concatLua

function table.concat<V>(t: { V }, separator: string?, i: number?, j: number?): string

Joins the items from index i to j into one string with separator between them. i defaults to 1, j to #t and separator to an empty string.

It reads t directly without calling __index.

Input
const words = { "red", "green", "blue", 7 }
print(table.concat(words, ", "))
print(table.concat(words, "-", 2, 3))
Output
red, green, blue, 7
green-blue

Every item in the range has to be a string or a number. Anything else is an error that names its index.

Freezing

table.freezeLuau

function table.freeze<T>(t: T): T

Freezes the table and returns it. After that, assigning to any key or setting its metatable is an error. Freezing is shallow: tables stored inside a frozen table can still change.

Input
const colors = table.freeze({ "red", "green" })
const ok = pcall(function()
    colors[3] = "blue"
    return true
end)
print(ok)
print(table.isfrozen(colors))
Output
false
true

Freezing a table that is already frozen is an error. So is freezing one whose metatable has a __metatable field.

table.isfrozenLuau

function table.isfrozen(t: {}): boolean

Returns true when the table is frozen by table.freeze or by the program that embeds Luwu.

Deprecated

table.getnLuaLuaudeprecated

function table.getn<V>(t: { V }): number

Returns the length of the array.

table.foreachLuaLuaudeprecated

function table.foreach<K, V>(t: { [K]: V }, f: (K, V) -> ())

Calls f with every key and value in the table in no particular order. When f returns a value other than nil, the loop stops and table.foreach returns that value.

table.foreachiLuaLuaudeprecated

function table.foreachi<V>(t: { V }, f: (number, V) -> ())

Calls f with every index and item from 1 to #t in order. When f returns a value other than nil, the loop stops and table.foreachi returns that value.