Could somebody explain for i, v in pairs

Well I get the basic concept of it, but like in which instances do you think I should use it in. Like I kinda just need somebody to explain it a little better… Thanks!

100 Likes

The generic for loop syntax goes a bit like this:

for var1, var2, etc in iterator, state, index do
end

for i, v in pairs(t) is a specific instance of this; pairs is a function which returns an iterator, the state passed to it, and nil. When you use this idiom, you’re using an iterator function which goes over every key-value pair in your table t, and moves it into i, v.

You’d use pairs(t) in your loop when you want to go over a dictionary, for example: {a = 1, b = 2, c = 3}. pairs doesn’t iterate in any specific order, but it goes over all key-value pairs.

There’s a second function by a similar named, called ipairs. As you’d expect it has similar behavior, and it’s used in the same way except for 2 important details. ipairs is used for arrays {1, 2, 3}, the result of inst:GetChildren(), etc. The order of the items i, v receives is also always guaranteed to be 1 through the largest index before it hits a hole in the container.

As for the actual syntax and commas generic for uses, you should probably disregard until you feel you might need to make your own custom iterators.

26 Likes

A table is like a box of things in it. Each thing in the box is labeled so that you know what it is.

When you use the pairs loop, you are looking at each item v and its label i. In more “computer science” terms, that’s considered the “value” and “index” (hence the v and i). The index is the label, which identifies the value.

You use it in just about any instance when you want to iterate over a table of items. Ideally, you would use ipairs if iterating over a table where all the indexes are numerical, in order, and start at 1 (i.e. a typical array). But if you have indices in the table that are non-numeric, then you want to use pairs to access them.

One possible use-case is having a table where the players act as the key/index, and points to another table with player data. You might want to use a pairs loop to get the data for all the players in order to save/transform/read it.

53 Likes

To understand pairs you should start off by reading https://developer.roblox.com/en-us/articles/Table to understand tables, arrays, and dictionaries.

Pairs are for dictionaries only. Dictionaries store values with a key-value pair, which then you can refer to the key to get the value. Keys(called indexes outside the context of dictionaries) don’t have to be a string, they can be anything (including instances/objects, and tables), and so can values. But commonly, keys are strings. An example of a dictionary: (The ones in the square brackets are the ‘keys’)

local t = {
["One"] =  "The First"
["Two"] = "The Second"
["Three"] = "The Third"
}
print(t["Three"]) -- The Third

So, what pairs does is iterate(go over) each key in a dictionary (but the order in which it iterates is not guaranteed AFAIK). So you use pairs when you want to go over all the values in a dictionary. Example: (assuming t is the same as before)

for i, v in pairs(t) do
print(i, v) -- prints the key-value pair (ex: Two, The Second)
end

Also, i,v are just variable names, you can name them anything you want but these are just the common names used. And as for ipairs (which only iterates over an array in order), I would not recommend it, use a numerical for loop instead .

18 Likes

First you have to understand what a table is. Arrays and dictionaries are types of tables, arrays are like this,

local array = { "Hello", 1, true}

As you can see, an array is basically a variable, but it holds more than one value.

print( array[1] )
print( array[2] )

This would print “Hello”, because the first time we were telling it to print the first value in the table, and the second time it will print “1” because we’re telling it to print the second thing in the array.

In pairs takes a table, and goes through it. For example:

local array = { "Hello", 1, true}

for i, a in pairs(array) do 
print(a)
end

a represents the value it is in middle of going through.
This would print in the output
Hello
1
true
i and a are just variables you can name them whatever you want.

this is very useful, let’s say you have a model, and you want to change every child of the model’s transparency to 0.5. instead of going through each part, you can just do this.

local children = game.Workpsace.Model:GetChildren()

for num, part in pairs(children) do
part.Transparency = 0.5
end

This works, because :GetChildren() returns a table with all the children of the model as the values.

24 Likes

Most of your post doesn’t add further context or clarity to mine, it practically goes over exactly what I went over in a very similar structure. That aside, you should fact-check things you aren’t certain about or add a disclaimer that it may not be fully accurate. Example

pairs does not iterate in a specific order, but here you are implying it does. If order matters, pairs should not be used. Which brings me to my next point, don’t use pairs on a table that’s not a dictionary (in other words, an array), it’s a bad practice.

The optimal way to do it:

local children = game.Workpsace.Model:GetChildren()

for num = 1, #children do -- commonly the variable is called 'i'
children[num].Transparency = 0.5
end

Not only do numerical for loops maintain order of arrays (which in this case doesn’t matter), they’re cleaner (as it only uses one variable instead of two) and faster (although negligible in practical use)

13 Likes

Really? When I tested it did it in order. Might have been a coincidence, idk

4 Likes

pairs will sometimes iterate in order if indexes are numerical/ if they are arrays:

local Table1 = {val1 = 5, Bar  = 6,  Foo = "Hello" , val_D = 56 }

local Table2 = {5, 6,"Hello", 56 }



for  _, v in pairs(Table1) do
	print(v) -->>>>   56  5  "Hello"  6  
end

for  _, v in pairs(Table2) do
	print(v) -->>>>   5 6 "Hello" 56
end

But as mentioned already you shouldn’t always rely on this or at least using ipairs is better if you needed to “ensure” an array is being iterated in order.

5 Likes

Being in order wasn’t even the point I was trying to make, so I couldn’t care less whether I said it in order or not. When I made the post, I just typed them in the output in order because it came naturally, not because I was trying to say that it will iterate in order.

3 Likes

Hi there,

for i,v in pairs() do is basically an advanced loop. This is used to iterate over a table, or I also use it to iterate over members of an Instance by using :GetChildren().

CODE SAMPLE

local table = {
  key = "value"
  key2 = "value2"
}

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

EXPECTED OUTPUT
Developer Console:

key value
key2 value2

Please note that the thing about pairs is that there is no predictable order it will iterate over, much unlike ipairs which iterates over arrays in a chronological order. For this reason, using ipairs to iterate over children is usually preferred as there is less opportunity for surprises to appear due to it being predictable.


Edit: You no longer need to use ipairs/pairs to iterate over arrays/dictionaries. You can now just do:

local table = {
  key = "value"
  key2 = "value2"
}

for i,v in table do
     print(i,v)
end
72 Likes

But you still gave a false implication by not stating that order is not guaranteed and showing the print in order. The problem isn’t that you typed it out in order, it’s that you didn’t mention that order is not specific. I shouldn’t have to explain what implications are.

3 Likes

It is basically an enhanced for loop. The i, v is defining variables for each i ndex and v alue of the table that you are iterating through. k for key is often used rather than i in most cases. pairs is your iterating function, it returns each index and value of the table. Another not so common one is ipairs , which functions the same for the most part except that it will stop the loop once it runs into a non-existent ( nil ) value. For example:

local myTable = {5, "pineapple", [23] = 6, ["foo"] = true}
for key, value in pairs(myTable) do
    print(key, value)
end
1       5           -- because we didn't define a key for the value 5, it defaulted to index 1.
2       pineapple   -- same case here, except they index is now 2.
23      6           -- we defined a key by using square brackets and we set the index to 23.
foo     true        -- keys can also be strings, and we can store any value we want in a table.
12 Likes

You shouldn’t iterate over an Instance’s children using pairs, it’s the least optimal for loop. For arrays, though both pairs and ipairs will work, using numerical for loops is optimal.

2 Likes

Very well explained, Crazyman32! Your answer halp me a lot understanding how it works :slight_smile:

2 Likes

@viindicater
I think you forgot the commas.

t = {
[“One”] = “The First”,
[“Two”] = “The Second”,
[“Three”] = “The Third”,
}

1 Like

Numeric for loops: Programming in Lua : 4.3.4
Generic for loops: Programming in Lua : 4.3.5

I am confident enough to say that any other sources than the ones specified above, should be ignored.

2 Likes

In simple terms, basically it means it goes through the selected values of a table.

1 Like

In summary the:

i,v

means that it runs through its key word, and then value, such as key value and key2 value

1 Like

this was solved so long ago I use it a lot now

2 Likes

then, print(i) will print key and key2
and print(v) will print value and value2 ?

1 Like