Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I sort a simple Lua table alphabetically?

Tags:

lua

lua-table

I have already seen many threads with examples of how to do this, the problem is, I still can't do it.

All the examples have tables with extra data. For example somethings like this

lines = {
  luaH_set = 10,
  luaH_get = 24,
  luaH_present = 48,
}

or this,

obj = {
   { N = 'Green1'      },
   { N = 'Green'       },
   { N = 'Sky blue99'  }
}

I can code in a few languages but I'm very new to Lua, and tables are really confusing to me. I can't seem to work out how to adapt the code in the examples to be able to sort a simple table.

This is my table:

local players = {"barry", "susan", "john", "wendy", "kevin"}

I want to sort these names alphabetically. I understand that Lua tables don't preserve order, and that's what's confusing me. All I essentially care about doing is just printing these names in alphabetical order, but I feel I need to learn this properly and know how to index them in the right order to a new table.

The examples I see are like this:

local function cmp(a, b)
   a = tostring(a.N)
   b = tostring(b.N)
   local patt = '^(.-)%s*(%d+)$'
   local _,_, col1, num1 = a:find(patt)
   local _,_, col2, num2 = b:find(patt)
   if (col1 and col2) and col1 == col2 then
      return tonumber(num1) < tonumber(num2)
   end
   return a < b
end

table.sort(obj, cmp)
for i,v in ipairs(obj) do
   print(i, v.N)
end

or this:

function pairsByKeys (t, f)
  local a = {}
  for n in pairs(t) do table.insert(a, n) end
  table.sort(a, f)
  local i = 0      -- iterator variable
  local iter = function ()   -- iterator function
    i = i + 1
    if a[i] == nil then return nil
    else return a[i], t[a[i]]
    end
  end
  return iter
end

for name, line in pairsByKeys(lines) do
  print(name, line)
end

and I'm just absolutely thrown by this as to how to do the same thing for a simple 1D table.

Can anyone please help me to understand this? I know if I can understand the most basic example, I'll be able to teach myself these harder examples.

like image 220
Alfie Stoppani Avatar asked Feb 01 '26 02:02

Alfie Stoppani


2 Answers

local players = {"barry", "susan", "john", "wendy", "kevin"}

-- sort ascending, which is the default
table.sort(players)
print(table.concat(players, ", "))

-- sort descending
table.sort(players, function(a,b) return a > b end)
print(table.concat(players, ", "))

Here's why:

Your table players is a sequence.

local players = {"barry", "susan", "john", "wendy", "kevin"}

Is equivalent to

local players = {
  [1] = "barry",
  [2] = "susan",
  [3] = "john",
  [4] = "wendy",
  [5] = "kevin",
}

If you do not provide keys in the table constructor, Lua will use integer keys automatically.

A table like that can be sorted by its values. Lua will simply rearrange the index value pairs in respect to the return value of the compare function. By default this is

function (a,b) return a < b end

If you want any other order you need to provide a function that returs true if element a comes befor b

Read this https://www.lua.org/manual/5.4/manual.html#pdf-table.sort

table.sort Sorts the list elements in a given order, in-place, from list[1] to list[#list]

This example is not a "list" or sequence:

lines = {
  luaH_set = 10,
  luaH_get = 24,
  luaH_present = 48,
}

Which is equivalent to

lines = {
  ["luaH_set"] = 10,
  ["luaH_get"] = 24,
  ["luaH_present"] = 48,
}

it only has strings as keys. It has no order. You need a helper sequence to map some order to that table's element.

The second example

obj = {
   { N = 'Green1'      },
   { N = 'Green'       },
   { N = 'Sky blue99'  }
}

which is equivalent to

obj = {
  [1] = { N = 'Green1'      },
  [2] = { N = 'Green'       },
  [3] = { N = 'Sky blue99'  },
}

Is a list. So you could sort it. But sorting it by table values wouldn't make too much sense. So you need to provide a function that gives you a reasonable way to order it.

Read this so you understand what a "sequence" or "list" is in this regard. Those names are used for other things as well. Don't let it confuse you.

https://www.lua.org/manual/5.4/manual.html#3.4.7

It is basically a table that has consecutive integer keys starting at 1.

Understanding this difference is one of the most important concepts while learning Lua. The length operator, ipairs and many functions of the table library only work with sequences.

like image 183
Piglet Avatar answered Feb 03 '26 04:02

Piglet


This is my table:
local players = {"barry", "susan", "john", "wendy", "kevin"}
I want to sort these names alphabetically.

All you need is table.sort(players)

I understand that LUA tables don't preserve order.

Order of fields in a Lua table (a dictionary with arbitrary keys) is not preserved.
But your Lua table is an array, it is self-ordered by its integer keys 1, 2, 3,....

like image 33
Egor Skriptunoff Avatar answered Feb 03 '26 06:02

Egor Skriptunoff