22. Tables as lists
A table is Lua's one and only built-in data structure. Depending on how you use it, the same table can hold a list of values, a dictionary of key-value pairs, or both. This chapter covers the list shape; the next, the dictionary.
Creating a list
A list is a table with values stored under keys 1,
2, 3, and so on. The easiest way to make one
is with curly braces:
local fruits = {"apple", "banana", "cherry"}
print(fruits[1]) -- apple
print(fruits[2]) -- banana
print(fruits[3]) -- cherryTwo surprises if you have seen other languages:
- Indexing starts at 1, not 0. The first item is at
[1]. Roblox follows the same convention. - Square brackets
[...]look up a value; the number inside is the index.
The variable fruits holds a reference to the table. The
braced values become the items at positions 1, 2, 3.
Length with #
The same # you used for strings works on lists. It
returns the item count:
local fruits = {"apple", "banana", "cherry"}
print(#fruits) -- 3
print(fruits[#fruits]) -- cherry (the last one)fruits[#fruits] reads the value at the position equal to
the length — the last one. A common pattern.
Looping over a list
Two natural ways to walk through a list.
Numeric for
If you only need the items, a numeric for from
1 to #t works:
for i = 1, #fruits do
print(i, fruits[i])
endOutput:
1 apple
2 banana
3 cherry
ipairs
ipairs is a built-in iterator that yields the index and
value in order, starting at 1:
for index, value in ipairs(fruits) do
print(index, value)
endSame output. ipairs is more idiomatic for lists because
it makes the intent — iterating in order — obvious.
Open exercises/22/01-list-loop.lua. Add a fourth fruit
and re-run. Both #fruits and the loop should adjust
automatically.
Adding and removing items
Two ways to append to a list:
local fruits = {"apple", "banana"}
table.insert(fruits, "cherry") -- appends to the end
fruits[#fruits + 1] = "date" -- also appends; manual version
print(fruits[3]) -- cherry
print(fruits[4]) -- datetable.insert(t, pos, value) inserts at pos
and shifts later items right:
table.insert(fruits, 1, "apricot") -- new first item
print(fruits[1]) -- apricot
print(fruits[2]) -- apple (shifted from 1 to 2)table.remove(t, pos) removes the value at
pos and shifts later items left. With no pos,
it removes the last:
table.remove(fruits, 1) -- drops "apricot"
table.remove(fruits) -- drops the new last itemSetting a slot to nil (fruits[2] = nil)
does not shift later items; it leaves a hole in the
list. After that, #fruits and ipairs may stop
counting at the hole. Use table.remove to drop a value
cleanly.
Tables are passed by reference
Tables behave differently from numbers and strings in one important way: assigning a table to another variable does not make a copy.
local a = {1, 2, 3}
local b = a -- b refers to the SAME table
b[1] = 99
print(a[1]) -- 99 (the change shows through a too)Both a and b name one table. For a real
copy you must loop and build a new table — there is no built-in
table.copy. You rarely need to.
Homework
Problem 1 — Favourite games
Open exercises/22/homework/01-favourite-games.lua.
Create a list of five game names. With a
for ... in ipairs(...) do loop, print each as
1. Roblox, 2. Minecraft, and so on.
Problem 2 — Sum the list
Open exercises/22/homework/02-sum-list.lua. A list of
numbers is declared at the top. Compute and print its sum.
Problem 3 — Insert and remove
Open exercises/22/homework/03-insert-remove.lua. The
starter has a short list. Do four things, printing the full list after
each step:
- Append a new item.
- Insert another item at position 1.
- Remove the last item.
- Remove the item at position 2.
Challenge — Reverse a list
Open exercises/22/homework/04-reverse.lua. Define a
local function reverse(list) that returns a new
list with the items reversed, leaving the original unchanged. Test it on
a list of strings and print both before and after.
Stuck or finished? Open the homework solutions page.