3

I have a lua table that contains 2 key pieces of data. I would like to sort the table in ascending order by the "num1" column, or if thats not possible, they by the key value in ascending order

Here's what I have so far:

local widgets = {}
widgets[1568] = {}
widgets[1568]["num1"] = 99999
widgets[1568]["val2"] = "NA"
widgets[246] = {}
widgets[246]["num1"] = 90885
widgets[246]["val2"] = "NA"
widgets[250] = {}
widgets[250]["num1"] = 95689
widgets[250]["val2"] = "NA"
widgets[251] = {}
widgets[251]["num1"] = 95326
widgets[251]["val2"] = "NA"
widgets[252] = {}
widgets[252]["num1"] = 95301
widgets[252]["val2"] = "NA"
widgets[256] = {}
widgets[256]["num1"] = 95303
widgets[256]["val2"] = "NA"

-- ATTEMPT TO SORT
--table.sort(widgets, function(a,b) return tonumber(a.num1.value) < tonumber(b.num1.value) end)
--table.sort(widgets, function(a,b) return tonumber(a.num1) < tonumber(b.num1) end)

--TRY SORTING BY ID:
table.sort(widgets, function(a,b) return tonumber(a) < tonumber(b) end)

for i, v in pairs(widgets) do
    print(v.num1)
end

Any suggestions would be appreciated. Right now, I'm reviewing Sort a Table[] in Lua to try to understand the "spairs" function. But that example is slightly different because I have a table within a table...

Thanks.

SOLUTION

In line with the answer below, I created a new table and added the records from the old table, one by one, using table insert like so:

local new_widgets = {}
for i, v in pairs(widgets) do
    table.insert(new_widgets, id=v.id, num1= v.num1, num2 = v.num2)
end

then I sorted new_wigets.

Community
  • 1
  • 1
dot
  • 14,928
  • 41
  • 110
  • 218
  • 4
    you will not be able to use `table.sort` for this, since the indices in your table do not start at 1 and run consecutively. internally, table.sort runs from 1 to #table, so it is not iterating the widgets. you'll have to roll your own sorting function and call it yourself. see the [lua docs about table.sort](http://www.lua.org/manual/5.2/manual.html#pdf-table.sort) to verify. your function will have to iterate the table with `pairs`. – Mike Corcoran Jun 11 '14 at 13:29

1 Answers1

5

Lua tables are hashtables. Their entries have no specific order.

You fake it by using consecutive numerical indices then iterating by incrementing a number (note: internally Lua actually will implement this as an array, but that's an implementation detail; conceptually, table entries have no specific order).

t[2] = "two"
t[3] = "three"
t[1] = "one"

for i=1,#t do print(t[i]) end

ipairs creates an iterator that does the same thing as this for loop.

So, if you want your data sorted, you need to put it in a table with consecutive numeric indices.

In your case, there's a lot of different ways you can do it. Here's one way to skin that cat:

Instead of this:

local widgets = {
    [246] = { num1 = 90885, val2 = "NA" }
    [250] = { num1 = 95689, val2 = "NA" }
    [251] = { num1 = 95326, val2 = "NA" }
    [252] = { num1 = 95301, val2 = "NA" }
    [256] = { num1 = 95303, val2 = "NA" }
}

You want this:

local widgets = {
    { id = 246, num1 = 90885, val2 = "NA" },
    { id = 250, num1 = 95689, val2 = "NA" },
    { id = 251, num1 = 95326, val2 = "NA" },
    { id = 252, num1 = 95301, val2 = "NA" },
    { id = 256, num1 = 95303, val2 = "NA" },
}

-- sort ascending by num1
table.sort(widgets, function(a,b) return a.num1 < b.num1 end)

for i, widget in ipairs(widgets) do
    print(widget.num1)
end

If you need the ability to then lookup a widget quickly by id, you can create a lookup table for that:

local widgetById = {}
for i,widget in pairs(widgets) do
    widgetById[widget.id] = widget
end
Mud
  • 28,277
  • 11
  • 59
  • 92
  • can you show me how to create the new table from the original? my original table is a result set from a database query which I can't change. – dot Jun 11 '14 at 17:28
  • I will try the table.insert – dot Jun 11 '14 at 18:05