# For Loops

Sep 25 2019, 1:58 PM PST 5 min

A Generic For loop is a type of `for loop` that takes advantage of iterator functions. You should understand basic for loops before learning this.

## Stateful iterators

First, let’s take a look at iterators. In layman’s terms, an iterator is a function that returns the next set of values each time it is called. Here’s a function that generates a simple iterator:

``````-- returns an iterator that counts letters between first and last
function letterIterator(first, last)
-- store the position that the iterator is at
local index = first
-- return the iterator - a function!
return function()
if index <= last then
-- move to the next character
index = index + 1
-- return the ascii representation of the index plus 95 (a letter)
-- note that there's only one value being returned
return string.char(index + 95)
end
end
end
``````

And here’s how we can use it:

``````local iterator = letterIterator(1, 4)
local letter

letter = iterator()
print(letter) -- **a**

letter = iterator()
print(letter) -- **b**

letter = iterator()
print(letter) -- **c**

letter = iterator()
print(letter) -- **d**

letter = iterator()
print(letter) -- nil

letter = iterator()
print(letter) -- nil
``````

As you can see, the iterator returned the first, second, third, and fourth letters, then stopped returning anything. At this point, there’s nothing left to iterate, so you should stop calling the iterator. That’s where the generic for loop comes in. We can write the previous code like this instead:

## Explanation

The iterator is the object that keeps track of how many times a for loop is supposed to run. This is different from a the numeric for loop in `Articles/Roblox Coding Basics Loops|Loops` in that the numeric for loop there is simply an index:

``````for i = 20, 1, -2 do
print(i)
end
``````

However, in the generic for loop, we get the values returned by the iterator function. In the iterator returned by `letterIterator()` above, we saw that `string.char(index + 95)`, not `index` itself, was returned. Here’s an example using multiple return values:

### Standard Library Iterators

Two commonly-used standard library iterator functions are `pairs` and `ipairs`. These functions return table keys and their corresponding `values`. pairs iterates through the entire table, even if the key is non-numerical (such as “Hi”), treating it as a `dictionary` (see `Articles/Table|Tables`). ipairs iterates through the table as if it were an array, starting at 1 and counting up consecutive integer indices. Once it hits a nil value, it will stop looping through the table. Also, please note that pairs does not iterate through the table in any particular order. Here’s an example of the difference:

``````local sampleTable = {
[1] = "A",
[2] = 2,
[3] = "B",
[5] = 5,
Hi = "C"
}
``````

Since pairs uses `next` as its iterator function, some people prefer to call it directly:

## Customized Iterators

You too can write your own iterators! Here are two useful examples:

#### string.gfind

This example returns multiple values:

#### descendants

This example iterates through all of the `Instance/GetChildren|children` of an `Instance|Instance`:

``````function descendants(obj, depth)
assert(obj and obj.GetChildren, "object parameter is missing or is not an instance")

local function yieldtree(obj, level)
if depth and level > depth then
return
end
for _, o in ipairs(obj:GetChildren()) do
coroutine.yield(o, level)
yieldtree(o, level+1)
end
end

return coroutine.wrap(function() yieldtree(obj, 1) end)
``````

Tags:
• lua
• coding
• concept