Search code examples
arrayslua

Sort array with some negative indexes


I'm discovering Lua (context: factorio scripting) and I'm quite puzzled by the loose typing. I'm trying to make a dictionary (int,structure) with an integer (and possibly negative key). And then sort it by that key.

local dic = {}
dic[1] = {t="foo"}
dic[25] = {t="bar"}
dic[-30] = {t="negative"}

table.sort(dic) -- oddly, that changes nothing

print(serpent.block(dic))
-- using ipairs() would make no sense for this structure
for k,v in pairs(dic) do
  print(serpent.line(k) .. " --> " .. serpent.line(v))
end

-- some processing that expects the array/dic/structure/thingy sorted by index

and that outputs

    {
      {
        t = "foo"
      },
      [-30] = {
        t = "negative"
      },
      [25] = {
        t = "bar"
      }
    }

-- sort didn't work
1 --> {t = "foo"}
25 --> {t = "bar"}
-30 --> {t = "negative"}

So, what am I doing wrong ?

Edit: thanks to answers, I now understand that ipairs() was not the right iterator for this data type. Removesd it from code for clarity


Solution

  • (answer by OP)

    After some hacking around, I managed to change my data structure to something that looks overkill, but at least it works

    Don't take that as an optimal solution...

    Instead of this (which does not sort, see answers)

    local dic = {}
    dic[1] = {t="foo"}
    dic[25] = {t="bar"}
    dic[-30] = {t="negative"}
    -- try to sort that
    

    ... which gives an unsorted and unsortable

    {
      {
        t = "foo"
      },
      [-30] = {
        t = "negative"
      },
      [25] = {
        t = "bar"
      }
    }
    

    I finally used

    local dic = {}
    table.insert(dic,  
      {key=1, value={t="foo", ...}}  
    )
    table.insert(dic,  
      {key=25, value={t="bar", ...}}  
    )
    table.insert(dic,  
      {key=-30, value={t="negative", ...}}  
    )
    
    -- sort with an explicit function
    table.sort(thresholds, 
      function(kv1,kv2) 
        return kv1.k < kv2.k end
    )
    
    for _,kv in pairs(dic) do
      -- processing
    end
    

    which gives a more complex, and sortable

    {
      {
        key=1,
        value= { t = "foo", ...}
      },
      ...
    }