# Iterators

Before we start, don't be like this guy

In Lua, iterators are functions that return a closure (function). This closure is called each time the iterator is called, and it returns the next value in the iteration sequence. You may already know some iterator functions such as ipairs or pairs. If you print them out, you would observe that they return a closure.

``````print(pairs({})) --  output: function: address	 table: address 	nil
``````

First, the function (next) is outputted, then the table inside the functions ({}), and then finally the starter index

To get started, you must first know what next is and what it does.

next is a function that is usually used to iterate over tables and returns the next key-value pair in a table following a given key. Key defaults to nil

``````next(Table, Key)
``````
``````local my_table = {
[1] = "a",
[2] = "b",
[3] = "c"
}

print(next(my_table))    -- 1 a
print(next(my_table, 1)) -- 2 b
print(next(my_table, 2)) -- 3 c
print(next(my_table, 3)) -- nil
``````

## Making our own iterator function

First, let's start making our own iterator function by recreating pairs We'll name our iterator function my_pairs From our previous test, we know that an iterator returns a function, a table, and a starter index. Let's use that to create a foundation for our script

``````local function my_pairs(mytable)
local index = nil
return function(mytable)

end, mytable, index
end

``````

Let's start working on our return function

As mentioned before, next returns the next key-value pair after you provide it a key (2nd parameter) Based off of that, lets add some code to our function.

``````local function my_pairs(mytable)
local index = nil
return function(mytable)
local key, value = next(mytable, index)
index = key
return key, value
end, mytable, index
end
``````

Let's dissect what we wrote

``````	local key, value = next(mytable, index)
``````

Here, we use the next function to get the next key-value pair after index (nil) Then, we set the key-value pair to their respective variables.

``````index = key
``````

We set the index to the key so after we loop back, we will start off with the new index

``````return key, value
``````

We finally return the key value pair Refer to the note at the bottom if you are confused on why a while/for loop wasn't used to repeat the process

Let's apply it into a for loop

``````-- table
local my_table = {
[1] = "a",
[2] = "b",
[3] = "c"
}

-- iterator function
local function my_pairs(mytable)
local index = nil
return function(mytable)
local key, value = next(mytable, index)
index = key
return key, value
end, mytable, index
end

-- for loop
for i, v in my_pairs(my_table) do
print(i,v)
end

--[[
Output:

1	a
2	b
3	c

]]--
``````

## Notes + end

Note: If you are by any chance confused why I didn't use a loop in the my_pairs function, the for loop does that for us. The for loop repeats the process until the function returns nil (this isn't special to our custom function). Though while loops can also be used to loop over a table using next, example below

``````-- table
local my_table = {
[1] = "a",
[2] = "b",
[3] = "c"
}

local function my_for(myTable, func)
local index = nil
while true do
local key, value = next(myTable, index)
if not key then break end;
index = key
func(key, value)
end
end

my_for(my_table, function(a,b) print(a,b) end)
``````

Due to the fact that the for loop will keep repeating until nil is returned, you can cause yourself to crash if you don't use it cautiously

Ex:

``````local function myPairs()
return function()
return 1,2
end
end

for i, v in myPairs() do
print(i,v)
end
``````
``````for v in function() return 1 end do end -- free roblox admin
``````

Since it never returns nil and never stops, it's basically the same as

``````while true do end
``````

Now that you have mastered the ways of iterator functions, you are now considered an epic roblox scripter Source: trust me

Note2: Yes yes I know iterators other than pairs and ipairs exist, and I may update this thread in the future to include coroutine iteration, ex:

``````for i in coroutine.wrap(function() coroutine.yield(1) end) do
print(i)
end
``````

Thank you for reading, I hope you found this somewhat useful!