sgtaziz
sgtaziz

Reputation: 383

Sort a Table[] in Lua

I have a Lua table that I am trying to sort. The table's format is as follows:

tableOfKills[PlayerName] = NumberOfKills

Which means, for example, if I had a player named Robin with a total of 8 kills and another named Jon with a total of 10 kills, the table would be:

tableOfKills[Robin] = 8
tableOfKills[Jon]   = 10

How would I sort that type of table to show the highest kills first? Thanks in advance!

Upvotes: 34

Views: 68131

Answers (2)

Ethan
Ethan

Reputation: 11

An alternative way of sorting that avoids iterators and such is to pass the table to a list of key-value pairs (i.e.: list = {{k1,v1}, {k2, v2}, ...}. Here's my solution:

local ranks = {}
for player,kills in pairs(tableOfKills) do
    table.insert(ranks, {player, kills})
end

-- Now we use Lua's built-in sort function with a short custom comparator function:
table.sort(ranks, function (a, b) return a[2] > b[2] end)

-- The only thing left to do is display the results:
for i=1,#ranks do
    print(ranks[i][1], ranks[i][2])
end

Upvotes: 0

Michal Kottman
Michal Kottman

Reputation: 16753

A table in Lua is a set of key-value mappings with unique keys. The pairs are stored in arbitrary order and therefore the table is not sorted in any way.

What you can do is iterate over the table in some order. The basic pairs gives you no guarantee of the order in which the keys are visited. Here is a customized version of pairs, which I called spairs because it iterates over the table in a sorted order:

function spairs(t, order)
    -- collect the keys
    local keys = {}
    for k in pairs(t) do keys[#keys+1] = k end

    -- if order function given, sort by it by passing the table and keys a, b,
    -- otherwise just sort the keys 
    if order then
        table.sort(keys, function(a,b) return order(t, a, b) end)
    else
        table.sort(keys)
    end

    -- return the iterator function
    local i = 0
    return function()
        i = i + 1
        if keys[i] then
            return keys[i], t[keys[i]]
        end
    end
end

Here is an example of use of such function:

HighScore = { Robin = 8, Jon = 10, Max = 11 }

-- basic usage, just sort by the keys
for k,v in spairs(HighScore) do
    print(k,v)
end
--> Jon     10
--> Max     11
--> Robin   8

-- this uses an custom sorting function ordering by score descending
for k,v in spairs(HighScore, function(t,a,b) return t[b] < t[a] end) do
    print(k,v)
end
--> Max     11
--> Jon     10
--> Robin   8

Upvotes: 107

Related Questions