Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How to sort dictionary by multiple variables?

Asked by 5 years ago

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
0
Dictionaries don't have an order so you cannot guarantee that there will be order with a dictionary. User#24403 69 — 5y

1 answer

Log in to vote
0
Answered by 5 years ago

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()
Ad

Answer this question