Sorting Arrays Help

Hi, How can sort arrays based on if the lap number is the highest and checkpoint number? I want it so that the player wit the highest lap number and checkpoint number is first. Here is my code:

while true do	
	for i, v in pairs(game.Players:GetPlayers()) do
		local PlayerIdTable = {}
		local LapNumberTable = {}
		local CheckpointNumberTable = {}
		
		
		table.insert(PlayerIdTable, v.UserId)
		table.insert(LapNumberTable, v:FindFirstChild("CurrentLapNumber").Value)
		table.insert(CheckpointNumberTable, v:FindFirstChild("CurrentCheckpointNumber").Value)
		local MasterTable = {PlayerIdTable, LapNumberTable, CheckpointNumberTable}
		
		print(#MasterTable)
	end
		wait(1)
end

There is a table.sort function which will help you here. In this example, I sort my leaderstats scores by Kills:

local playerScores= {}
local score = {}
for i, player in pairs(players:GetPlayers()) do
	score = {player.UserId, player.Name, player.Team.Name, player.leaderstats.Kills.Value, player.leaderstats.Deaths.Value}
	table.insert(playerScores, score)
	sortedTable = table.sort(playerScores, function(a,b)return a[4] > b[4] end)
end

Firstly, if you want to store the ids, laps and checkpoints of every player into same tables, you shouldn’t create a new table for every player in the loop that goes through the table returned by the Players:GetPlayers() function. Also, I don’t understand what the Mastertable is for and, based on what you put into it, I’m pretty sure it shouldn’t be unique to every player either.

I made something that should work for getting a table with the playerids in right order and it doesn’t make big changes to what you already have (just fixes the scope problems and removes the mastertable, which seems useless). However, it would probably be a better idea to not create new tables and sort all the playerids every second, but instead only do sorting when there’s a change in a value. Anyways, here it is.

local function shouldBeBefore(laps, checkpoints, laps2, checkpoints2)
	return laps > laps2 or (laps == laps2 and checkpoints >= checkpoints2)
end

local function getSortedIds(plrIds, lapNumbers, checkpointNumbers)
	local sortedPlayerIds = {}
	for i, v in ipairs(plrIds) do
		if #sortedPlayerIds == 0 then
			sortedPlayerIds[1] = v
			continue
		end
		local laps, checkpoints = lapNumbers[i], checkpointNumbers[i]
		local newIndex, biggestSmallerLaps, biggestSmallerCheckpoints
		
		-- compare the values to the values of the players on the sortedPlayerIds table
		for iSorted, v2 in ipairs(sortedPlayerIds) do
			local i2 = table.find(plrIds, v2)
			local laps2, checkpoints2 = lapNumbers[i2], checkpointNumbers[i2]
			if shouldBeBefore(laps, checkpoints, laps2, checkpoints2) and (not newIndex or shouldBeBefore(laps2, checkpoints2, biggestSmallerLaps, biggestSmallerCheckpoints)) then
				newIndex, biggestSmallerLaps, biggestSmallerCheckpoints = iSorted, laps2, checkpoints2
			end
		end
		if not newIndex then -- if the value shouldn't be before any other value that is currently in the sortedPlayerIds table then
			-- add the value to the end of the table
			sortedPlayerIds[#sortedPlayerIds+1] = v
		else -- place it to the correct index and move values with equal or bigger index to higher indexes
			table.insert(sortedPlayerIds, newIndex, v)
		end
	end
	return sortedPlayerIds
end


while true do	
	local PlayerIdTable = {}
	local LapNumberTable = {}
	local CheckpointNumberTable = {}
	
	for i, v in pairs(game.Players:GetPlayers()) do
		table.insert(PlayerIdTable, v.UserId)
		table.insert(LapNumberTable, v:FindFirstChild("CurrentLapNumber").Value)
		table.insert(CheckpointNumberTable, v:FindFirstChild("CurrentCheckpointNumber").Value)
	end
	
	local orderedPlayerIds = getSortedIds(PlayerIdTable, LapNumberTable, CheckpointNumberTable)
	-- Here you can do things with the ordered player ids
	wait(1)
end

If you just want to sort the values in the LapNumberTable and the CheckpointNumberTable, you can use table.sort as @BadDad2004 said. However, it doesn’t directly give you the playerid or player, so I don’t think it is what you want, and if you gave the ordered tables to my function, the function wouldn’t work. Here’s an example of that anyway.

local function sortFunction(a, b)
    return a > b
end
table.sort(LapNumberTable, sortFunction)
table.sort(CehckpointNumberTable, sortFunction)
1 Like

So, how will I be able to see who’s in 1st-8th place?

The first value in the table returned by my function is the userid of the player who’s in the 1st place, the second value is the userid of the player who’s in the second place, and so on.

local firstPlayerId = orderedPlayerIds[1]
local secondPlayerId = orderedPlayerIds[2]
local eighthPlayerId = orderedPlayerIds[8]
1 Like

This is probably going to be a stupid question but how do I do a remote event to send their places so that the number shows up on the UI?

If you want to show each player their own position, maybe this would work for you.

On the server:

for i, v in ipairs(orderedPlayerIds) do
    RemoteEvent:FireClient(game.Players:GetPlayerByUserId(v), i)
end

On the client:

local textGui = -- the gui object
RemoteEvent.OnClientEvent:Connect(function(pos)
    textGui.Text = tostring(pos)
end)

I’m getting an error with this line saying GetPlayersFromUserID isn’t a member of players? Should I change it to GetPlayers instead?

I just checked the API reference page of the Players service and noticed that the function is actaully called GetPlayerByUserId. I’ve edited the reply with the code now.

So what will pos come out to be? a number or something?

Nevermind, needed to use tonumber. Thank you so much!