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.
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
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.
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??
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
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.
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 Tableis 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.
There’s such thing as a mixed table. This is not a very reliable check. typeof is also ridiculously slow, so I’d recommend type where possible. Also, please don’t edit in a reply that answers a reply further down in the thread, it breaks the continuity of the thread.
The typeof was just because I’m used to using that for validating Roblox-specific datatypes, type should be used here probably.
Obviously not reliable, that’s the reason why I said it would only work for defining ‘typical’ tables (where it is either a dictionary or an array, was only a quick edit to my post), for example using that algorithm it would print {} as a dictionary which it technically isn’t.
I left an extra end there by mistake
Anyways, since I don’t have access to Studio, I wrote this in Lua 5.3.5
local tab = {1, nil, 1}
local function nilfound(t)
local i = 0
for _, _ in pairs(t) do
i = i + 1
end
if i - #tab ~= 0 then return true end
end
setmetatable(tab, {
__tostring = function(self)
if nilfound(self) then return "nil found, cannot perform operation" end
local indexes, result, numericalindex = {}, nil, nil
for k, _ in pairs(self) do
if type(k) == "number" then numericalindex = true end
if type(k) ~= "number" and numericalindex then return "mixed table" end
table.insert(indexes, k)
end
if #indexes == 0 then return "empty table" end
if #self ~= #indexes then result = "dictionary"
else
result = "array"
end
return result
end
})
print(tab) --> cannot perform operation
Edit:
+This code was optimized to work better for various cases.
Just adding this here: typeof was optimized in Luau
@ zeuxcg
Optimize typeof() to run ~6x faster. It used to be that type() was much faster than typeof() but they now should be more or less comparable.
Where in my post does it say a table is not a valid type, or that an array and a table are different types?
I was only suggesting that saying
type(t)
would return anything different from what calling type(t) would return where t is either a table or array is incorrect.
I’m just saying even if it were an array, type(t) would still return “table” so I won’t say that’s a reliable check to differentiate between a numerically indexed table or a dictionary.
Keep in mind that even this convoluted of a check will still consider local tab = {1, 2, nil, 3, [true] = "there"} an array, so there’s not an ideal way to check for this.
Considers almost every case possible, if the table contains nil then it’ll not do anything because it’s not any of the three, (for the nil part, I had to resort to the forum and an unexpectedly simple function).