# Behaviour of looping through tables

Hey there, so I was playing a bit with tables and noticed some behaviour I can’t seem to understand.

Example1

``````local TestTable = {}

TestTable[2] = "twoooo"
TestTable[1] = "onee"
TestTable[3] = "three"
TestTable[5] = "fivee"
TestTable[8] = "eight"
TestTable[7] = "seven"

for i,v in pairs(TestTable) do
print(i)
print(v)
end

--[[
OUTPUT:
1
onee
2
twoooo
3
three
5
fivee
7
seven
8
eight
]]
``````

Example2
The only thing changed is that I removed TestTable[2] = “twoooo”

``````local TestTable = {}
TestTable[1] = "onee"
TestTable[3] = "three"
TestTable[5] = "fivee"
TestTable[8] = "eight"
TestTable[7] = "seven"

for i,v in pairs(TestTable) do
print(i)
print(v)
end

--[[
OUTPUT:
1
onee
5
fivee
8
eight
7
seven
3
three
]]
``````

In Example1, the order in which the table is printed, is in the order of the lowest number to the highest number.

In Example2, the order in which the table is printed, is in a random order. So not from the lowest number to the highest number.

Is there a reason why the order in which the numbers are printed has changed?

1 Like

Basically, when using `pairs`, the table is not guaranteed to iterate in an ascending order. If you were wanting to get the table to iterate in a guaranteed ascending order, then you will need to use `ipairs` which will increment in a numerical order until a index is `nil`, so this means missing the index `2` would cause the the iteration to come to a end.

2 Likes

Hello @speeddecoolste!
This issue is because of the fact that the iterator `pairs`. It prints a table everything regardless of whether the key is numerical or not.

`ipairs` on the other hand loop numerically in order. If it ever comes by a nil or a non-numerical key, it does not print that key or anything proceeding after it.

``````local tab = {}

tab["four"] = 4
tab[1] = "one"
tab[2] = "two"
tab[3] = "three"
tab[5] = "five"

for i, v in pairs(tab) do

print(i, v)

end

--[[this prints...

1 one
2 two
3 three
four 4
5 five

--]]

for i, v in ipairs(tab) do

print(i, v)

end

--[[however, this ONLY prints...

1 one
2 two
3 three

--]]
``````

Notice how `ipairs` did not print the key “four”. In fact, it does not even print anything after it, because as you can see, it did not print key “5”.

You can learn more in this article. It covers `pairs` and `ipairs` in the section “Standard Library Iterators”.

I hope that helped you.

1 Like

`next` isn’t guaranteed to iterate in order.

It should iterate in order for an array, but for other things like a dictionary (or what you’re doing), there isn’t a very clear way to iterate through the table, so it does what it thinks is best.

Adding the elements in the table constructor for the second example fixes the unintended behavior you’re experiencing.

``````local TestTable = {
"onee",
nil,
"three",
nil,
"fivee",
nil,
"seven",
"eight"
}
for i,v in pairs(TestTable) do
print(i,v)
end
``````

This example makes it much more clear that it should be an array, so it iterates correctly.

When you added the elements with `TestTable[x] = value` it was likely being added to the hash part of the table instead of the array part.

3 Likes