Search code examples
sortinglualua-tablecomputercraft

Iterate over table in order of value


Lets say I have a table like so:

{
   value = 4
},
{
   value = 3
},
{
   value = 1
},
{
   value = 2
}

and I want to iterate over this and print the value in order so the output is like so:

1
2
3
4

How do I do this, I understand how to use ipairs and pairs, and table.sort, but that only works if using table.insert and the key is valid, I need to be loop over this in order of the value.

I tried a custom function but it simply printed them in the incorrect order.

I have tried:

  • Creating an index and looping that
  • Sorting the table (throws error: attempt to perform __lt on table and table)
  • And a combination of sorts, indexes and other tables that not only didn't work, but also made it very complicated.

I am well and truly stumped.


Solution

  • Sorting the table

    This was the right solution.

    (throws error: attempt to perform __lt on table and table)

    Sounds like you tried to use a < b.

    For Lua to be able to sort values, it has to know how to compare them. It knows how to compare numbers and strings, but by default it has idea how to compare two tables. Consider this:

    local people = {
        { name = 'fred', age = 43 },
        { name = 'ted', age = 31 },
        { name = 'ned', age = 12 },
    }
    

    If I call sort on people, how can Lua know what I intend? I doesn't know what 'age' or 'name' means or which I'd want to use for comparison. I have to tell it.

    It's possible to add a metatable to a table which tells Lua what the < operator means for a table, but you can also supply sort with a callback function that tells it how to compare two objects.

    You supply sort with a function that receives two values and you return whether the first is "less than" the second, using your knowledge of the tables. In the case of your tables:

    table.sort(t, function(a,b) return a.value < b.value end)
    
    for i,entry in ipairs(t) do
        print(i,entry.value)
    end