How can I use in pairs?

Hello, I have no problem here, but I am failing to come up with a concept that uses in pairs, does anybody have an example? Thanks.

And no need to come up with a script, only concepts.

And also, I will not add a solution, since there isn’t really a solution to this question.

3 Likes

If you need to go through a table, a table is a collection of values, objectvalues, numbervalues, boolvalues etc.

If for example you need to update the color of all parts in a folder, you can do

for i, part in pairs(Folder:GetChildren()) do --The :GetChildren() returns a table of all of the folder's contents.
part.BrickColor = --whatever color
end

the “i” value is the number of iterations that has been currently done. so after going through 3 parts, the i will be 3. the “part” is the value that it’s currently at.

5 Likes

Oh, now I can see that as a clean way to change colors!

1 Like

You would need to look into for loops to use in pairs. Most scripts using in pairs look something like this:

for i,v in pairs (game.workspace:GetChildren()) do -- Filters though every brick in workspace
if v:IsA('Part') then -- Checking each part in workspace to see if it is a part
v.BrickColor = BrickColor.New('Really Red') -- altering the specific part
end
end

These are incredibly useful for things like vehicle hitboxes or for applying effects to multiple bricks in your game by iterating the array that is returned by the in for loop. You can read up on more about them on the API here:

6 Likes

O: I can see that as very useful!

They are also used a lot when creating things like admin scripts to filter though settings to see who is an admin etc and for games that might have whitelisted players who if their name is in a script they get a special tool etc

2 Likes
for i, v in pairs(game.Players:GetPlayers()) do -- Looping through the players
if v:FindFirstChild("IsKiller") then -- Checking to see if they have a value in them
v.Character.HumanoidRootPart.CFrame = game.workspace.KillerSpawn.CFrame + Vector3.new(0,10,0) -- Changing the killers postition
game.ReplicatedStorage.Int.Value = "Starting game..." -- Setting the game to start
end
end

This is part of a basic loop for a round based game.

1 Like

Generic for: https://www.lua.org/pil/4.3.5.html
Numeric for: https://www.lua.org/pil/4.3.4.html

These can be used in a lot of things, like looping through players to kick them:

for _, Player in ipairs(game:GetService('Players'):GetPlayers()) do
    Player:Kick('You have been kicked!')
end

ipairs vs pairs (difference):
https://stackoverflow.com/questions/55108794/what-is-the-difference-of-pairs-vs-ipairs-in-lua

1 Like

@InternallyAmplified GetChildren() returns an array, not a table.
Edit: an array is a type of table.


In pairs is normally used for loops considering an objects children. A child is basically something that is under an object.

pairs is basically a simplified function that tells the script what to do, pairs is almost the same as doing this:

function pairs(Table)
    for i = 1, #Table do
         return i, Table[i] -- "i" is the index while "Table[i]" is the object corresponding to the index
    end
end

This is what pairs could be used for:

for i, v in pairs(workspace:GetDescendants()) do -- "i" is the "i" and "v" is the "Table[i]"
    v.Name = i -- Makes the name of the object the index
end

Index is the numeric value of something: 1, 2, 3, 4, etc.


Replying to @xNick_O’s post below:

pretend I have a table:

local Table = {"a", "b", "c". "d"}

Then I do:

print(Table[4])

It will print "d".

I was just the index, so if I were to loop through that table with the index:

for i = 1, #Table do
    print(Table[i]) -- prints "a", then "b", then "c", then "d"
end

The Number sign # is just to tell how many things are in a table or array.

2 Likes

Why do you put a number sign before Tab;e and those brackets by i?

1 Like

I know it returns an array, i am simplifying it for him because i assume he doesnt know what tables / arrays are.
Figuritavely speaking though, they’re both the same if you think about it:

Item:GetChildren() = {Item.Part1, Item.Part2 etc…} So that’s why i reffer to both of them as tables

also @xNick_O he puts the [x] after table, (x being a number) to make refference to the xth item in that table

Table = {“one”, “two”, “four”, “nine”}, Table[4] = “Nine”

1 Like

That’s only when iterating over numerical indices. pairs just returns the next iterator function, the index- be it numerical or a string along with the associated value, whatever variables you pass i.e i, v they contain the values returned.

Technically still a table though, the term ‘array’ is just by Roblox standards, a table with numerical indices.

https://www.lua.org/pil/7.3.html
https://www.lua.org/pil/4.3.5.html

My reply here should be good for reference : Question regarding looping - #6 by un1ND3X


pairs is very often used in the wrong situations, always use ipairs to iterate over contiguous arrays, unless you want to iterate in arbitrary order with negligible increased speed.

The example I used doesn’t matter if you use in pairs or ipairs

It won’t affect the outcome, but examples like these are what sprout incorrect usage of pairs, if you can iterate a tiny bit faster then why not??

1 Like

You can also use in pairs to use a function for multiple parts. For example, if you wanted multiple parts to kill a player, you could put all of them in a folder named “Kill Bricks”. You would then use “in pairs” to apply a kill function for all those parts.

local killparts = workspace:FindFirstChild("Kill Bricks")

for _, v in pairs(killparts:GetDescendants()) do --gets all descendants of the folder
    if v:IsA("BasePart") then --checks if the current object is a part (it could possibly be a model, and we don't want that)
        v.Touched:Connect(function(hit) --If any part inside the folder is touched
            local character = hit:FindFirstAncestorOfClass("Model")
            if character and character.Humanoid then
                character.Humanoid.Health = 0
            end
        end)
    end
end
1 Like

The example I used doesn’t matter if you use in pairs or ipairs

1 Like

If they both have the same outcome, then it doesn’t matter which one you use. Plenty of people I know would use in pairs for a function like that.

1 Like

Then they’re missing out on micro-optimization, unless they’re iterating over non-list items (a dictionary for example) in which case pairs is just supposed to be used.

From another post of mine:

Again, it’s clearly just clearly negligible difference , there shouldn’t be too much of a difference unless you’re using pairs for traversing a huge array and using the counter index.

A table and an array aren’t different datatypes, so

print(type({['Key'] = "value"}))
-- and
print(type({"value"}))
-- will both print 'table'
-- to check for a typical table, do

 local tab = {}
 if type(tab) == "table" and #tab ~= 0 then 
    print("array") 
    else 
    print("dictionary")
end

@Abysmallow all posts made before this explain its usage, that should be enough for concept. Just use it as an iterator to reduce the amount of code, when you need to perform multiple repetitive operations for multiple objects, for example.

1 Like

Ok, but I’m just trying to give him an example of using in pairs, not ipairs. Yes it’s faster, but he’s asking about in pairs

1 Like

I found this post a bit misleading, so I just want to correct a few misconceptions:

An array is just a type of table with numeric incremental (aka 1, 2, 3) indexes. I’m not sure this is a nitpick worth making, since it is still a table.

You really should not be using in pairs for looping through an instance’s children. ipairs is generally preferred for arrays, and GetChildren will always return an array. ipairs is preferred partially because it’s faster, but also because it makes it clear what type of indexes you’re going to be expecting within the loop.

That function will only return 1 and the first element of Table; return immediately stops a function. It also completely ignores the fact pairs will loop through non-numeric indexes, like in {["hey"] = "yo"}

GetDescendants also returns an array, so ipairs should also be used here. I’m also not sure how helpful "i" is the "i" is, since that wouldn’t have helped me at all as a beginner.

Indexes can be any type. You can even index a table with a table! For example:

local t = {}
t[t] = t -- the value of the table at the position which is itself would be itself

print(t[t][t] == t) --> true

(I’m sure this is just a typo)

I mean, technically, it prints d. The quotation marks just signify that it’s a string in the code, they don’t appear in the output

I found this a bit misleading, so this is just to clarify: for i = 1, #Table do will just make a loop run once for each item of the table. i is simply a number that goes up each time. Since Table is an array in this case, any number between 1 and its length is a valid index, since that’s the definition of an array. It’s not really looping through the table like ipairs or pairs are, though, it’s just counting up from 1 to the table’s length in a way that happens to be useful for indexxing an array. This is pretty nitpicky and doesn’t really make a difference, but I think the distinction is important because it helps show how for i = x, y, z can be useful in other scenarios too.

That only works for arrays, not all tables. It won’t count non-numeric indexes. For example, a table like {["hey"] = "yo"} would have a length of 0.

6 Likes

nil and NaN aren’t valid table keys.

local t = {}
t[nil] = 1 --> table index is nil
local t = {}
t[0/0] = 1 --> table index is NaN
4 Likes

Please don’t confuse others, it returns a table indexed by numeric keys. It’s still a table, don’t believe me? Use type(t), considering t is a table.

2 Likes