You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? I want to be able to name each TextButton a number, ranging from 1-10 using tables.
What is the issue? I can’t seem to figure out how to create an efficient loop to do so.
What solutions have you tried so far? Looking on the devforum hasn’t helped for me and Youtube.
for i,v in pairs(script.Parent:GetChildren()) do
if v:IsA("TextButton") then -- Checks to see if the child is a textbutton
local numrandomtable = {1, 2, 3, 4, 5, 6, 7, 8, 9 ,10}
local alreadyPicked = {}
local picked = 0
for i = 1, 10 do
repeat
picked = numrandomtable[math.random(1, #numrandomtable)]
until not table.find(alreadyPicked, picked) -- Checks to see if the random number has been selected
table.insert(alreadyPicked, picked)
v.Name = picked
end
end
end
The code looks ok, but you could try this if you want efficiency:
local random_numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-- If you want to call this loop multiple times, you will need to reset the random_numbers each time.
for i,v in pairs(script.Parent:GetChildren()) do
if v:IsA("TextButton") then -- Checks to see if the child is a textbutton
local picked = math.random(1, #random_numbers)
local number = random_numbers[picked]
v.Name = tostring(number)
table.remove(random_numbers, picked) -- Remove it from the array so it won't be picked again.
end
end
How many TextButtons are there? Because the code above assumes 10.
I see that you put it in ReplicatedFirst as a local script. My intentions were to leave in a GUI as a serverscript but now I assume that it will only work as a local script. Is that the case?
Another method would be to shuffle the table and then just iterate in order:
-- https://stackoverflow.com/a/68486276
local function ShuffleInPlace(t)
for i = #t, 2, -1 do
local j = math.random(i)
t[i], t[j] = t[j], t[i]
end
end
local boxes = script.Parent:GetChildren()
ShuffleInPlace(boxes)
for i, v in boxes do
if v:IsA("TextBox") then
v.Name = tostring(i)
end
end
I apologize for being vague, but my intentions were to make this script run in a regular ScreenGui. Despite your code working in ReplicatedFirst as a LocalScript, it doesn’t work when I try it this way. Is there any way to make it so it runs as a server script in a gui?
-- What is the number of numbers?
local NUMBER_RANGE = 10
-- Used to store what numbers have already been used
local UsedNumbers = {}
-- Gets a number that has not yet been used
-- Warns "All numbers used, re-using a random one" if no unused ones exist
-- Will always return a number within the range
local function GetRandomUnusedNumber() : number
if #UsedNumbers >= NUMBER_RANGE then
-- All numbers were used, fall back
warn("All numbers used, re-using a random one")
return math.random(1, 10)
else
-- If there are unused numbers, pick a random one
local NumberOptions = {}
local PickedNumber
for Number = 1, NUMBER_RANGE do
if not table.find(UsedNumbers, tostring(Number)) then
-- If the number has not been used, add it to options to pick from
table.insert(NumberOptions, tostring(Number))
end
end
PickedNumber = NumberOptions[math.random(1, #NumberOptions)]
table.insert(UsedNumbers, tostring(PickedNumber))
return PickedNumber
end
end
-- Resets the data containing what numbers were use
local function ResetUsedNumbers()
UsedNumbers = {}
end
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
-- Testing:
for _ = 1, 12 do
local Number = GetRandomUnusedNumber()
print(`Selected number: {Number}`)
end
ResetUsedNumbers()
for _ = 1, 5 do
local Number = GetRandomUnusedNumber()
print(`Selected number: {Number}`)
end
Sample output:
--[[
Selected number: 4 - Server - Script:38
Selected number: 9 - Server - Script:38
Selected number: 8 - Server - Script:38
Selected number: 5 - Server - Script:38
Selected number: 3 - Server - Script:38
Selected number: 10 - Server - Script:38
Selected number: 2 - Server - Script:38
Selected number: 6 - Server - Script:38
Selected number: 7 - Server - Script:38
Selected number: 1 - Server - Script:38
All numbers used, re-using a random one - Server - Script:9
Selected number: 6 - Server - Script:38
All numbers used, re-using a random one - Server - Script:9
Selected number: 9 - Server - Script:38
Selected number: 7 - Server - Script:45
Selected number: 4 - Server - Script:45
Selected number: 5 - Server - Script:45
Selected number: 8 - Server - Script:45
Selected number: 3 - Server - Script:45
--]]
Here is a function that you can use. It can be called as many times as needed.
local function NameRandomNumbers(items)
local random_numbers = {}
-- Add a number for each child.
for i = 1, #items do
random_numbers[i] = i
end
-- This loop shuffles the numbers and renames each child randomly.
for i,v in pairs(items) do
-- This only works for textbuttons, but you can change it by removing the if statement.
if (v:IsA("TextButton")) then -- Checks to see if the child is a textbutton
local picked = math.random(1, #random_numbers)
local number = random_numbers[picked]
v.Name = tostring(number)
table.remove(random_numbers, picked) -- Remove it from the array so it won't be picked again.
end
end
end
-- Example of how you might use it.
NameRandomNumbers(script.Parent:GetChildren())