Generic for and break
Use generic for with pairs/ipairs and control loop flow with break.
Generic for and break is a free Lua Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Generic for Protocol
Lua's generic for loop works with an iterator function. The syntax is for vars in iter_func, state, init do. On each iteration, Lua calls iter_func(state, lastVar) and assigns return values to vars. The loop stops when the first return value is nil.
-- Manual use of next() iterator
local t = {a=1, b=2, c=3}
local key, val = next(t, nil) -- first entry
while key ~= nil do
print(key, val)
key, val = next(t, key) -- advance
endpairs() for All Keys
pairs(t) returns an iterator that traverses all key-value pairs in a table, including string keys, integer keys, and mixed. The iteration order for non-integer keys is unspecified (hash order). Array portion and hash portion are both included.
local config = {
host = "localhost",
port = 8080,
debug = true,
[1] = "first",
}
for key, value in pairs(config) do
print(key, value)
end
-- Prints all 4 entries in any orderipairs() for Array Keys
ipairs(t) iterates over integer keys starting from 1, stopping at the first nil value. It is safe, predictable, and preserves order. Use ipairs for array-like tables when order matters and you want to stop at the first hole.
local fruits = {"apple", "banana", "cherry"}
for i, fruit in ipairs(fruits) do
print(i, fruit)
end
-- 1 apple
-- 2 banana
-- 3 cherry
-- stops at first nil
local t = {10, 20, nil, 40}
for i, v in ipairs(t) do
print(i, v) -- only 1,10 and 2,20
endpairs vs ipairs
Know when to use each: ipairs is for ordered sequential arrays; pairs is for dictionaries or mixed tables. ipairs stops at the first nil hole; pairs visits every non-nil key. For pure arrays, ipairs is more idiomatic.
local mixed = {10, 20, key="val", 30}
-- ipairs only sees array part in order
print("ipairs:")
for i, v in ipairs(mixed) do
print(i, v) -- 1:10, 2:20, 3:30
end
-- pairs sees everything
print("pairs:")
for k, v in pairs(mixed) do
print(k, v) -- 1:10, 2:20, 3:30, key:val
endCustom Iterator with Closure
You can write your own iterator as a closure. The factory function returns a stateful closure that advances position on each call. When there is nothing left to return, it returns nil to stop the generic for.
local function range(from, to, step)
step = step or 1
local i = from - step
return function()
i = i + step
if i <= to then return i end
end
end
for n in range(1, 10, 2) do
io.write(n .. " ")
end
print() -- 1 3 5 7 9string.gmatch as Iterator
string.gmatch(s, pattern) returns an iterator over all matches of the pattern in string s. It is commonly used to split strings, extract tokens, or find all occurrences of a pattern.
local sentence = "the quick brown fox"
for word in string.gmatch(sentence, "%a+") do
print(word)
end
-- the
-- quick
-- brown
-- foxbreak in Generic for
You can exit a generic for loop early using break. This is useful for searching: iterate until a match is found, then break. After breaking, execution continues at the statement after end.
local inventory = {
{name="sword", damage=50},
{name="shield", armor=30},
{name="bow", damage=35},
}
local target = "shield"
for i, item in ipairs(inventory) do
if item.name == target then
print("Found at index", i)
break
end
endModifying Tables During Iteration
Never insert or remove keys from a table while iterating with pairs() — the behavior is undefined (some changes may be seen, others skipped). If you need to modify a table, collect changes in a temporary list and apply them after the loop.
local t = {a=1, b=2, c=3, d=4}
local toDelete = {}
-- Collect keys to delete
for k, v in pairs(t) do
if v % 2 == 0 then
toDelete[#toDelete+1] = k
end
end
-- Delete after iteration
for _, k in ipairs(toDelete) do
t[k] = nil
end
-- t = {a=1, c=3}Enumerate Pattern
When you need both the index and the value, use ipairs which provides both. When you only need values and don't care about the index, you can use _ as a conventional "don't-care" variable name for the index.
local colors = {"red", "green", "blue"}
-- With index
for i, color in ipairs(colors) do
print(i .. ": " .. color)
end
-- Ignore index with _
for _, color in ipairs(colors) do
print(color) -- just the values
endnext() Directly
next(t, key) is the underlying traversal function. It returns the next key-value pair after key, or nil if there are no more. next(t, nil) gives the first entry. You can use next(t) ~= nil to check if a table is non-empty — faster than counting.
local function isEmpty(t)
return next(t) == nil
end
print(isEmpty({})) -- true
print(isEmpty({1,2,3})) -- false
print(isEmpty({a=1})) -- falseQuick Check
Which iterator stops at the first nil hole in a table?
Recap: Generic for and break
Summary:
pairs(t)— all keys, any orderipairs(t)— integer keys 1..n, ordered, stops at nil- Custom iterators: return a closure that returns nil to stop
breakexits the loop early- Never modify a table mid-pairs; collect changes and apply after
next(t) == nil— fast empty check
Frequently asked questions
Is the “Generic for and break” lesson free?
Yes — the full text of “Generic for and break” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.
What will I learn in “Generic for and break”?
Use generic for with pairs/ipairs and control loop flow with break. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Generic for and break” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- if, elseif and else Statements
- while and repeat-until Loops
- Numeric for Loop
- Generic for and break