Hi! In my current code, I have a dictionary that has a key with players name, which then gives a value that is their ranking. If I am given the value, how could I get the key from it?
When given [“PlayerOne”] = 1, how could I get “PlayerOne” from dictionary[1]?
EDIT: This allows you to find the player name with Table[1] and the Value with Table[2]. It also gets rid of the length operator issues (not sure what they’re technically called) revolving around that.
You need to iterate over the dictionary until you find a matching value.
Example:
local dictionary = {
["PlayerOne"] = 1,
}
local function getKeyFromValue(tab, input)
for key, value in pairs(tab) do
if value == input then
return key
end
end
end
local key = getKeyFromValue(dictionary, 1)
That said, there are probably better solutions to your problem. Searching for a key based on a value might not always return what you want (because of things like float number inaccuracies), and if the dictionary is large, it can be slow. You might want to reconsider the way you store and interface with your player data.
Answering your lower question, it is handling a max of 12 player’s data instantaneously, then it removes it. This is in-game ranking, so after 120 seconds it disappears.
For some reason, the code is returning nil. I’m using it recursively while looping through the dictionary that is filled with players to numbers. Do you have any idea as to why it won’t work? Do you need any code?
If you are using anything other than integers, you may be running into floating point precisions errors and may want to include an epsilon in your query.
What types of values are you storing and what are you planning on using this for?
Essentially, the game uses 3 variables to determine how well a player did. This comes out to the equation ab + c^2. Using this, I create a dictionary with the users name, and their Universal Ranking Value (URV) of the match. From there, I graphically represent it on UI, and then put it back into a loop to reward coins. For the sorting algorithm, I have to use the number as the key to make sorting easy, but because of that I’m not sure how I can do it the other way. Although as I write this, I can create 2 tables, inverses of eachother.
I’m attempting to do that, but am ending up with a nil value every time. I’m going to input the code, the looping has just been getting me with the different values. Thank you!
for i, player in pairs (players) do
local userCoinsCollected = game.Players.PlayerURV:FindFirstChild(player.Name).CoinsCollected
local userTimeSurvived = game.Players.PlayerURV:FindFirstChild(player.Name).TimeSurvived
local userSurvived = game.Players.PlayerURV:FindFirstChild(player.Name).Survived
game.Players.PlayerURV:FindFirstChild(player.Name).Value = userTimeSurvived.Value * userSurvived.Value + userCoinsCollected.Value * userCoinsCollected.Value
print(game.Players.PlayerURV:FindFirstChild(player.Name).Value .. " is the URV")
URVs[player.Name] = game.Players.PlayerURV:FindFirstChild(player.Name).Value
print(URVs[player.Name])
end
table.sort(players, function(playerA, playerB)
return URVs[playerA.Name] > URVs[playerB.Name]
end)
local leaderboardFinal = {}
x = 1
for i, v in pairs(URVs) do
print(URVs[i] .. "Testing")
leaderboardFinal[URVs[i]] = x
local key = getKeyFromValue(URVs, i)
URVInverse[URVs[i]] = key
x = x + 1
end
b = 1
for i, v in pairs(leaderboardFinal) do
print(i .. "is here")
print(tostring(URVs[i]) .. "Gets " .. b .. " coins!" )
--game.Players:FindFirstChild(key).leaderstats.Coins.Value = game.Players:FindFirstChild(key).leaderstats.Coins.Value + b
b = b + 1
end
I use this solution quite a bit in my own code, however, in this case I can see a couple of major problems that you would have to overcome (and potential solutions):
Firstly, I don’t think he can use a function like this because two players can have the same rating and that could result in data loss as the table would just return the first matching value it sees. However, you could solve this problem by making a copy of the table and using table.remove until the function returns nil.
Also, as you mentioned yourself, floating point precision is an issue. I would not use use an epsilon because, in rare cases, you could end up matching the data incorrectly. Instead, I would round the players’ rank or use integers in the formula so that you can compare them using the ‘==’ operator.
I don’t think he can use a lookup table this way because users could potentially have the same ranking meaning data may be lost. However, you could solve this by doing something like:
lookup[y] = lookup[y] or {}
table.insert(lookup[y], x)
And then iterating through that table to get all players with a certain ranking.
This section appears to be where you’re going wrong.
for i, v in pairs(URVs) do
print(URVs[i] .. "Testing")
leaderboardFinal[URVs[i]] = x
local key = getKeyFromValue(URVs, i)
URVInverse[URVs[i]] = key
x = x + 1
end
Instead, this will allow you to create the inverse table.
function invert(t)
local i = {}
for k, v in pairs(t) do
i[v] = k
end
return i
end
Then you just call this method on the table you want the inverse of to invert it.
He didn’t actually need to assign to a specific index. He just needed to have a table with players data in it, and then be able to sort that table in numeric order.