Chase
Chase

Reputation: 59

Lua sort array by key values

I've got an array of 32 elements set up like so:

racers[i] = {plCP = 0, plPos = 0}

I'd like to sort this array by the value plCP, and set plPos to be the value that the sort came up with. Something like this:

racers[1] = {plCP = 3, plPos = 3}
racers[2] = {plCP = 2, plPos = 4}
racers[3] = {plCP = 6, plPos = 2}
racers[4] = {plCP = 12, plPos = 1}
racers[4] = {plCP = 6, plPos = 2}

Also note that it is possible for 2 items to have the same plCP value. I'd like for them to have the same plPos value in these cases.

This is for a racing game I'm working on, and I'm trying to calculate the position of the player in the race based upon which checkpoint they're currently driving towards.

Upvotes: 3

Views: 6205

Answers (2)

darkfrei
darkfrei

Reputation: 586

You can make the function to get the comparing function:

function sortByKey(key)
    return function(a, b)
        return a[key] < b[key]
    end
end

local people = {
    { name = "Alice", age = 25 },
    { name = "Bob", age = 32 },
    { name = "Charlie", age = 18 },
    { name = "Dave", age = 42 },
    { name = "Eve", age = 29 }
}


table.sort(people, sortByKey("age"))
print ('    sorted by age:')
for i, v in ipairs (people) do
    print (i, v.name, v.age)
end

table.sort(people, sortByKey("name"))
print ('    sorted by name:')
for i, v in ipairs (people) do
    print (i, v.name, v.age)
end

Result:

    sorted by age:
1   Charlie 18
2   Alice   25
3   Eve 29
4   Bob 32
5   Dave    42
    sorted by name:
1   Alice   25
2   Bob 32
3   Charlie 18
4   Dave    42
5   Eve 29

Upvotes: 0

Piglet
Piglet

Reputation: 28974

Please refer to the Lua reference manual:

https://www.lua.org/manual/5.3/manual.html#pdf-table.sort

table.sort (list [, comp])

Sorts list elements in a given order, in-place, from list[1] to list[#list]. If comp is given, then it must be a function that receives two list elements and returns true when the first element must come before the second in the final order (so that, after the sort, i < j implies not comp(list[j],list[i])). If comp is not given, then the standard Lua operator < is used instead. Note that the comp function must define a strict partial order over the elements in the list; that is, it must be asymmetric and transitive. Otherwise, no valid sort may be possible. The sort algorithm is not stable: elements considered equal by the given order may have their relative positions changed by the sort.

table.sort(racers, comp) will do the trick if you implement a function comp that tells Lua which of two elements comes first.

Simple example:

local animals = {
     {name = "bunny", size = 4},
     {name = "mouse", size = 1},
     {name = "cow", size = 30}
}
-- sort animals by size descending
table.sort(animals, function(a,b) return a.size > b.size end)

for i,v in ipairs(animals) do print(v.name) end

print()

-- sort animals by size ascending
table.sort(animals, function(a,b) return a.size < b.size end)
for i,v in ipairs(animals) do print(v.name) end

All you need to do is to copy a few values around, once you know the order. Or you write your own sorting algorithm.

Upvotes: 4

Related Questions