How to sort table by value and then print index in order

I would like to create a table t using the following format.

t[uniqueID] = order

The uniqueID will be unique but order can be either same or different each time.

And then I would like to sort the table in ascending order so I can print the uniqueID accordingly.

My Code:

t = {}

function compare(a, b)
    return a[2] < b[2]
end

function printid()
    for k, v in pairs(t) do
        print(k)
    end
end

function main()
    t[5] = 47
    t[6] = 45
    t[7] = 49
    table.sort(t, compare)
    printid()
end

The result I get:

5
6
7

The result I expect:

6
5
7

How can I get the result I want?

2 answers

  • answered 2018-07-11 03:24 Henri Menke

    From “Programming in Lua” section 19.3 “Sort”.

    A common mistake is to try to order the indices of a table. In a table, the indices form a set, and have no order whatsoever.

    That means you have to put the pairs of table t into another table sorted which then has continuous indices. This table can then be sorted based of the predicate you defined. Furthermore you have to use ipairs when iterating a continuously indexed table because in pairs the order is unspecified.

    local t = {}
    
    t[5] = 47
    t[6] = 45
    t[7] = 49
    
    local sorted = {}
    for k, v in pairs(t) do
        table.insert(sorted,{k,v})
    end
    
    table.sort(sorted, function(a,b) return a[2] < b[2] end)
    
    for _, v in ipairs(sorted) do
        print(v[1],v[2])
    end
    

    Live on Wandbox

  • answered 2018-07-11 03:25 Curtis F

    pairs doesn't iterate in any particular order (regardless of whether or not it's sorted).

    table.sort only works on lists -- tables that use the keys [1], [2], [3], ..., [#list].


    You want a list of IDs in sorted order. This means

    1. make a list of IDs
    2. sort them by their associated values

    In code,

    local ids = {}
    
    -- Order of insertion doesn't matter here since we will sort
    for id in pairs(t) do
        table.insert(ids, id)
    end
    
    -- Sort the list of IDs by the values associated with each
    table.sort(ids, function(a, b)
        return t[a] < t[b]
    end)
    
    for i = 1, #ids do
        print(ids[i])
    end
    --> 6
    --> 5
    --> 7