3

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.

1
  • please read the Lua manual. It's all in there. Commented Apr 3, 2018 at 8:49

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

5 Comments

My problem with this is the part at the end: "The sort algorithm is not stable: elements considered equal by the given order may have their relative positions changed by the sort." I know there will be equal values.
@Chase and how is this a problem? if you know how to sort them properly?
I've messed around with this a bit and it changes the indexes of the list. I want the items in the list to retain their indexes. For example, if racers[6].plCP is 12, and all the rest of the values are 0, then it changes the index of racers[6] to racers[1] because it has the highest value. It's important that the index (6 in this case) remains the same because that's where the player's ID is stored. How would I make it so the index remains the same, but the value of plPos is changed?
Yes, that's what "sorting" means, in any language, it rearranges the values doing something like tmp = arr[6]; arr[6]=arr[1]; arr[1]=tmp. If you want to change the entries themselves, instead of rearranging array, you'd need to do something different. Since lua passes table arguments by reference, you might be satisfied with sort function like this: funtion(a,b) if a.plCP<b.plCP then a.plCP, b.plCP = b.plCP, a.plCP end return false end. It'd probably be a good style to make sure that your usage of side effects is explicit, however, if you intend your code to be used or seen by others.
@Chase maybe you should do a few Lua tutorials and work on your basics. Problems like yours are super easy to solve if you have a bit more experience. also try writing it down in normal words. then translate it into Lua
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.