What's the difference between numeric and generic loop?

Hey, I was wondering. What’s the difference between numeric and generic loop? I understand that numeric is like:
for i = 1, 10, -1
generic:
for i, v

I get it that numeric loops can be ran for a specific amount of times, but what about generic loop? Can it be specified to run a certain amount of time? Right now I just understand index and value for the generic loop. Thanks in advance! :smiley:

7 Likes

Generic loops are generally paired with the pairs() function to iterate over a table

local myTable = {10, 20, 30, 40, 50}
for i, v in pairs(myTable) do
    print(string.format("index: %d\tvalue: %s", i, v))
    if i == 3 then
        break
    end
end

This example code will print

index: 1	value: 10
index: 2	value: 20
index: 3	value: 30

Notice how it breaks at the third index? We can still do conditionals with the index and values of the table, it’s essentially just a nicer looking way to loop through tables.
More reading here: Programming in Lua : 7.2

4 Likes

Also ipairs will stop if it gets to a part of the table that the table doesn’t have.
Say there’s a table[1] a table[2] and a table[4] if you were to ipairs them then it would stop after 2 and not reach 4 because there is no 3.

Here’s the wiki

2 Likes

Generic loops are usually used when you do not know the number of items in a certain table, or if the number of items in a table is subject to change.

For example, a numeric for loop would not be effective to use when getting the amount of players in the game since that number is constantly changing. Instead we would do something like this:

for i,v in pairs(game.Players:GetChildren()) do
print(v.Name) -- Prints a list of all the names of the players in the game.
end

We can still use the i variable in a generic loop to get the specific iteration and add parameters to stop at that iteration, but if we for instance wanted to make a list of all the even numbers 1-10 then a numeric loop would be more effective. See here:

for i=2,10,2 do
print(tostring(i)) --Iterator goes up by two every time instead of one.
end
10 Likes

Numeric loops are very different from generic loops.

Numeric:

for Name=Start,End,Increment do

end

Generic:

for rets... in generator,state,control do

end

In the generic loop generator keeps getting called until the loop breaks itself or generator returns nil. Whats returned first by generator will become the control the next time generator is called. Everything returned by generator will be show up in rets....

for _ in print,1,2 do end
--> 1  2

The numeric loop works more like a counter, increment of 0 causes an infinite loop, increment less than 0 causes the loop to break when the new value is less than End, increment greater than 0 causes the loop to break when the new value is greater than End.
(breaking manually also works)

for i=1,5,2 do
    print(i)
end
--> 1
--> 3
--> 5
for i=5,1,-2 do
    print(i)
end
--> 5
--> 3
--> 1
2 Likes

This is inaccurate. The table generated by GetChildren and GetPlayers does not change when players leave/enter and could also be iterated by a numeric.

4 Likes

Let me clarify what I meant, the number can be different every time you get the table.

Plug regarding this code: GetPlayers is the canonical way to fetch players. I don’t recommend using GetChildren. You can use it but it’s not proper. GetPlayers functions like GetChildren but only for Player instances.

This still doesn’t change the fact you can still use a numeric loop with #, so it’s not a good example. The better use case would be when iterating a table where either you need the key and value or where you simply don’t want to index it as an array using a numeric for.

With generic for loops there’s 2 commonly used iterators, pairs() & ipairs(), which do have some difference. The difference is that pairs() returns a key-value pair with no key order however ipairs() returns a index-value pair with a key-order of a lower to higher index also non-numeric keys are ignored.
Example:
Pairs:

local t = {}
t[2] = "a"
t[4] = "b"
t[3] = "c"
t[1] = "d"
t["Yo"] = "yo!"
for i, v in pairs(t) do
    print(i, v)
end

Expected output:
2 a
4 b
3 c
1 d
Yo yo!

Ipairs:

t[2] = "a"
t[4] = "b"
t[3] = "c"
t[1] = "d"
t["Yo"] = "yo!"
for i, v in ipairs(t) do
    print(i, v)
end

Expected output:
1 d
2 a
3 c
4 b

1 Like