Hello! I would like to know if it’s possible to receive a percentage of elements from a table.
In other words, let’s say we have a table with length n. I want to get p% of the elements in this table. So if p==50 and n==4, I would want to get two of the elements. (preferably two random elements)
Currently, the way I would be doing this is something along the lines of this: (this also shows why I want to do it)
local percentage = 50
local plrs = game.Players:GetPlayers() --we will alter this table later on
local selectedPlrs = {} --place the selected players in here
for _ = 1,math.floor(#plrs/(100/percentage)) do --get the amount of players according to the percentage given
local random = math.random(1,#plrs) --get a random number based off of plrs table
table.insert(selectedPlrs,plrs[random]) --place the randomly selected player into selectedPlrs
table.remove(plrs,random) --remove it from the table so it doesn't get selected twice
end
But this just feels… oddly unnecessary? I would like to know if there’s a better way to do it.
(Sorry in advance if I shouldn’t post stuff when I basically already have a working script… lol)
--note, this means you must not have an element as nil
local function getPercentageElements(t, percentage)
local newT = t
Random.new():Shuffle(newT)
percentage = math.floor(math.clamp(tonumber(percentage) and math.floor(tonumber(percentage)) or 100, 0, 100)/100*#t)
return percentage == 0 and {} or table.pack(table.unpack(t, 1, percentage))
end
print(getPercentageElements({5, 6, 1, 2}, 50))
I haven’t necessarily tested it, but it looks like it might work.
So you want to get x random element/s from a table based on the percentage (p) of the total elements on the table (n).
local percentage = 0.5 -- 50 != 50%
local players = game.Players:GetPlayers():: {Player}
local totalNumOfPlayers = #players
local totalToGet = math.floor(totalNumOfPlayers * percentage) -- change if you don't want `math.floor`
local selectedPlayers = {}:: {Player?}
function getUniqueRandomNumbers(min: number, max: number, total: number)
if total <= 0 then
return {}
end
if max - min + 1 < total then
error("Too few numbers in range to meet the total unique requirement.")
end
local numbers = {}
for i = min, max do
table.insert(numbers, i)
end
local selected = {}
for i = 1, total do
local index = math.random(1, #numbers)
table.insert(selected, numbers[index])
table.remove(numbers, index)
end
return selected
end
for _, i in getUniqueRandomNumbers(1, totalNumOfPlayers, totalToGet) do
table.insert(selectedPlayers, players[i])
end
return selectedPlayers
I wasn’t aware of the Shuffle method, that actually helps alot. By the way, from my understanding you have to do Random.new():Shuffle(table)
This does work, although I’ve had to make a few changes to the rest of my code, but that’s okay.
The issue I was having is made clear by the documentation for table.pack(): “Returns a new table with all arguments stored into keys 1, 2, etc. and with a field “n” with the total number of arguments.”
It was adding on some other element to the table that I believe is just the length of the table. Not sure what the point of it is.
Again, this doesn’t need to be fixed as I’ve already done so myself. Thanks so much!
(for anyone coming from the future, in my case simply doing “t[“n”] = nil” works.)