Table Comprehensions
A table comprehension builds a new table from a loop, in one expression.
In Luau, you'd create an empty table and fill it:
const numbers = { 1, 2, 3, 4 }
local doubled = {}
for _, n in numbers do
table.insert(doubled, n * 2)
end
print(#doubled)In Luwu, you write the loop inside the table:
const numbers = { 1, 2, 3, 4 }
const doubled = { for _, n in numbers give n * 2 }
print(#doubled)give says what goes into the table for each item.
Comprehensions are also faster because Luwu sizes the table up front instead of growing it.
Filtering with when
Add when clauses to skip items. They work like the ones in if local.
const scores: { [string]: number? } = { ada = 92, alan = 67, grace = 88 }
const passed = {
for name, score in scores
when score >= 70
give name
}
print(#passed)A when clause can bind a value for the give to use:
const prices: { [string]: number? } = { apple = 1.25, pear = 0.8 }
const basket = { "apple", "kiwi", "pear" }
const costs = {
for _, fruit in basket
when const price = prices[fruit]
give price * 2
}
print(costs[1], costs[2])Building maps
Give [key] = value to build a map instead of an array.
const players = { "Ada", "Grace", "Alan" }
const name_lengths = {
for _, player in players
give [player] = #player
}
print(name_lengths.Grace)[key] += value adds to the value already stored under that key.
const words = { "red", "blue", "red", "green", "red" }
const counts = {
for _, word in words
give [word] += 1
}
print(counts.red, counts.blue)Destructuring items
The loop header can destructure each item.
const people = {
{ name = "Ada", age = 36 },
{ name = "Tom", age = 12 },
}
const adults = {
for _, .{ name, age } in people
when age >= 18
give name
}
print(adults[1], #adults)Several loops
Chain for clauses to loop inside a loop. This flattens a grid into an array:
const grid = {
{ 1, 0, 2 },
{ 0, 3, 0 },
}
const filled = {
for _, row in grid
for _, cell in row
when cell ~= 0
give cell
}
print(#filled)Items that need statements
When one item takes a few steps, end the clauses with do instead of give. The block follows the rules of a do expression: it ends with give, and continue skips the item.
const lines = { "hp=10", "", "mp=four" }
const settings = {
for _, line in lines
when line ~= ""
do
const key, value = string.match(line, "^(%a+)=(%d+)$")
value or continue
give `{key}: {value}`
}
print(#settings, settings[1])do is short for give do. You can write either.
Things to know
- A comprehension must be the only thing inside its braces.
- A nil item is skipped and never leaves a hole in the array.
- Numeric loops work too:
{ for i = 1, 10 give i * i }. - Luau's
table.insertloop still works, but a comprehension is shorter and faster.