Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to sort dictionary by multiple variables?

so, I don't have an error on this script, but rather I am seeking expansion on it - right now, it sorts a dictionary "kill table" by value, and after that is done, it writes to a "rank table" (called "placetable" here). what i want to happen before it writes to the rank table is it also sorts each kill numbers ascending by the least death down to the most before it goes downward to another variable. in other words, how a standard leaderboard in video games work. i have thought of a few ways on how this could be done without seeking help but they have all fallen flat.

note that the "death table" is also a dictionary but is not sorted in any specific way.

function getkeyssortedbyvalue(tbl, sortFunction)
  local keys = {}
  for key in pairs(tbl) do
    table.insert(keys, key)
  end

  table.sort(keys, function(a, b)
    return sortFunction(tbl[a], tbl[b])
  end)

  return keys
end

function updateleaderboardtables()
	local place = 0
	
	placetable = {}
	
	local sortedkill = getkeyssortedbyvalue(killtable, function(a, b) return a > b end)
	
	for _, key in ipairs(sortedkill) do
		place = place + 1
		placetable[key] = place
 	 print(key, killtable[key])
	end
end

1 comment

0

Dictionaries don't have an order so you cannot guarantee that there will be order with a dictionary.

1 answer

✓ Accepted answer

Note that when functions don't rely on global variables, you often have less bugs. For clarity, I recommend using camelCase for variable and function names - another Lua convention more rarely used on Roblox is like_this.

You will benefit from merging your dictionaries together into a single "class"/table that represents all relevant statistics. Instead of a separate dictionary for kills and another for deaths, have a single dictionary for both. Then when you go to sort it, you can make your sorting function more complicated:

local killtable = { -- example data (of course you'd have players rather than "a", "b", etc)
	a={Kills=5, Deaths=3},
	b={Kills=5, Deaths=9},
	c={Kills=5, Deaths=1},
	d={Kills=6, Deaths=10},
	e={Kills=4, Deaths=0},
	f={Kills=4, Deaths=10},
}

function getKeysSortedByValue(tbl, sortFunction)
	local keys = {}
	for key in pairs(tbl) do
		table.insert(keys, key)
	end

	table.sort(keys, function(a, b)
		return sortFunction(tbl[a], tbl[b])
	end)

	return keys
end

function updateLeaderboardTables()
	placetable = {}

	local sortedkill = getKeysSortedByValue(killtable, function(a, b) return a.Kills > b.Kills or (a.Kills == b.Kills and a.Deaths < b.Deaths) end)

	for place, key in ipairs(sortedkill) do
		placetable[key] = place
		print(key, killtable[key].Kills, killtable[key].Deaths)
	end
end
updateLeaderboardTables()

This discussion is preserved as it was. New answers, comments, and votes are closed.