How to loop through players

Hello! My name is Eli, and I’d like to know how to loop through players. This kind of embarrases me, because is should know for loops by now. Well, I do know them. But not looping through tables. Anwyays, I’d like help. Here is my script so far:

   print('Loading match script')
   local numplayer = game.Players.NumPlayers
local enoughplayers = 1
local status = game.ReplicatedStorage:WaitForChild('Status')
wait(0.4)
print('MatchScript: there is curently ' .. numplayer .. ' player(s) online')
print('Starting loop')
while true do
    print('Waiting..')
 status.Value = 'Waiting..'
wait(0.4)
if numplayer <=enoughplayers then
	print('Enough players!')
	status.Value = 'Choosing simon..'
	local plrs = game.Players:GetPlayers()
	local randomplr = plrs[math.random(1,#plrs)]
	game.ReplicatedStorage:WaitForChild('Simon').Value = randomplr.Name
	wait(2)
	local simon = game.ReplicatedStorage:WaitForChild('Simon')
	print(simon.Value .. ' is the simon')
	status.Value = simon.Value .. ' is the simon!'
	
	--for i = what
	
end
end

I would really appreciative help. Thanks!

6 Likes

You would do:

for i,v in pairs(game.Players:GetChildren()) do
-- v is your player
end
17 Likes

You can use pairs to run through a table. The Players service has a method called GetPlayers(), which returns an unsorted list of all players in the game.

You can iterate through them like so:

local Players = game:GetService("Players") -- you should use GetService over game.Players!
for _, player in pairs(Players:GetPlayers()) do
    -- this code will run for all players
end

Note that if the loop is broken, returned, or an error occurs the loop will stop.


You should always have helpful variable names, and not use unneeded variables.

for i,v in pairs(array) do
   -- we may not need i here
   -- besides, what is v meant to be??
end

Your code should always be optimized for reading!!

5 Likes

You should use ipairs over pairs. GetPlayers returns an array, ipairs runs quicker and it’s idiomatic for contiguous arrays. pairs is designed more for a dictionary where your keys aren’t known (noting that it returns next).

Use cases aside, it’s also good for collaborators and being clear as to what part of the table you’re intending to traverse through. I know when I see ipairs I understand that an array is being iterated over.

7 Likes

Well it’s a good idea, might work but in all honesty it’s not quite efficient (very inefficient).

@ElliottLMz Firstly I don’t see the need to index all players , on top of unnecessarily iterating through them in key, value pairs. It would take significantly less time returning values through index, value pairs, that is in ipairs, which I recommend you to use over in pairs for this case.

@TheWorstOne_2

Here’s a sample of what you would do to print players’ names , by iterating through an array of players :

    
   local Players = game:GetService("Players")
     
       Players.PlayerAdded:Connect(function()--each time a player is added
   --// Loop through all existing players and..print everyone's name
      for _, player in ipairs(Players:GetPlayers()) do
        print("Player name : ".. player.Name)
     end
   end)

However if you would want to not print everyone’s name each time a player joins, you could save the player’s names in table to prevent duplicate prints, like :

 local Players = game:GetService("Players")
   
  Current_Players = {}--we will save player's names here
    
  Players.PlayerAdded:Connect(function()--each time a player is added
--// Loop
   for _, player in ipairs(Players:GetPlayers()) do
       if Current_Players[player.Name] then--if he is already in the table then
	 return--or you could do if table.find(Current_Players,player.Name) etc.
  end
      table.insert(Current_Players,player.Name)
    print(player.Name.. " has joined the game")
    
  end
end)

@ElliottLMz

what do you mean?
v here would be the player, it’s necessary,
also using pairs here is a terrible idea as we don’t actually need to go through key value pairs, as @PostApproval already mentioned something similar , your code would also not work at all, unless you connect the loop to an event , that runs after players actually exist in the game. (like players.PlayerAdded)

2 Likes

I was honestly just answering the question on how to loop through all players quickly and not trying to give the most efficient way (I should have)

1 Like

What does “idiomatic for contiguous arrays” mean? I’m not quite understanding the advantage ipairs has over pairs.

ipairs runs faster for arrays ({"this", "is", "an", "array"). This is also reccomended by Roblox.

It’s easy to just pick pairs to iterate over any table but that often is a product of not understanding ipairs or what’s going on behind a for loop.

ipairs is designed to iterate over the array part of a table at an incremental level (index i+1 per iteration). ipairs will also guarantee ordered iteration and terminate at the first hole in an array. ipairs also makes it clear that what you’re iterating over is an array.

pairs, on the other hand, is designed to iterate over the hash part of a table. pairs is slightly slower because the keys aren’t known to the generator at the start, so it calls next to find which key-value pair should be iterated over next.

LuaU optimisations sped both generators up by a large amount, however ipairs saw the greater increase as noted by some benchmarks at RDC 2019 for the Lua As Fast As Possible presentation.

2 Likes

Using pairs, the iterator function is the next function, meaning if a value isn’t found for each key then it would return nil rather than stop the loop.

Ipairs on the other hand, iterates through index value pairs rather than key value pairs, and if nil is encountered through 1 to #t then the loop would stop.

Using Index value pairs (in ipairs ) also requires lesser time as no value is associated with keys, for example :

 for  i = 1 ,#t
   print ( t[i] ) 

Use ipairs where speed matters, and key value association is unnecessary.

Slightly unrelated: but is ipairs a recent thing? I’ve seen older scripts do:

local fruits = {"Apple", "Pear", "Pineapple", "Grapes"}

for i=1, #fruits do
    local fruit = fruits[i]
end

Was this to keep code fast before ipairs?

ipairs is not recent, it has existed since old versions of Lua (so for years). A numeric for loop was more common to use before LuaU optimisations because for whatever reason, Roblox’s implementation of ipairs was reported as noticeably slow enough not to use it. ipairs now sits as the fastest generator.

Will recomend you to use for i,v in pairs

FX. for i,v in pairs(game.Players:GetChildren()) do
i: is how many times the loop has looped and v: is the players
Hope that makes sense

As afforementioned, that is an inefficient method. Moreover, this topic is already solved.

  • i and v are unclear
  • You should be using GetService
  • ipairs is more efficient for arrays
1 Like

's not how pairs works. i, v is a key-value pair of an associative array and pairs specifically traverses through the hash part of a table implementing next to search for the next pair.

1 Like

There is 2 ways to use for i,v in pairs u can do
local fruits = {“Apple”, “Pear”, “Pineapple”, “Grapes”
for i=1, #fruits do
local fruit = fruits[i]
print(fruit)
end
or just do what i just said

Those are different and the one you just posted does not implement pairs. Pairs is a generator for a generic for loop, what you wrote is a numeric for loop. Numeric for loops deal in incremental indices and lookups only. You have an array so use ipairs. Scroll up for more information.

Reading material on for loops:
Programming in Lua : 4.3.4 - Numeric for
Programming in Lua : 4.3.5 - Generic for

2 Likes

Ohhh, well thx for the help i didn’t know that

Hello, I’m sort of new In scripting, May I ask why sometimes in “for” you need to have “`i, v” what both of the characters stand for? Thanks for the solution tho.

The first value in this case is index, how many times you’ve looped so far. V is the value of the list.
You need them because it’s for _,v in pairs, which is why there’s two values, it’s a pair.
Also you shouldn’t necrobump, especially 3 years later. There’s plenty of explanations out there for that.

Could somebody explain for i, v in pairs