• Subject: Re: sorting non-numeric keys table with custom function ?
• From: Michal Kottman <k0mpjut0r@...>
• Date: Wed, 24 Feb 2010 14:26:07 +0100

```On St, 2010-02-24 at 14:11 +0100, Valerio Schiavoni wrote:
> hi Luiz
>
> On Wed, Feb 24, 2010 at 1:14 AM, Luiz Henrique de Figueiredo
> <lhf@tecgraf.puc-rio.br> wrote:
> >> can anyone explain me how to sort a table whose keys are strings using a
> >> custom sorting function ?
> > What do you expect from a sorted table with string keys?
> > That pairs will list the entries in order?
>
> I was expecting pairs sorted according to the specified sorting
> function, if given.

No, pairs() iterates over the entries in an unspecified order. Quote
from the manual:
http://www.lua.org/manual/5.1/manual.html#pdf-next

> The order in which the indices are enumerated is not specified, even
for numeric indices.

This is from the documentation for the function next(), which pairs()
uses.

In order to iterate over the keys of a table in a sorted way, you can
use code like this:

function sortedpairs(t)
local keys = {}
for k in pairs(t) do table.insert(keys, k) end
table.sort(keys, function(a,b)
if tonumber(a) and tonumber(b) then
return a < b
else
end
end)
local i = 0
return function()
if i < #keys then
i = i + 1
return keys[i], t[keys[i]]
end
end
end

I'm sure this code can be simplified a lot, I use a custom function,
which orders numbers numerically, and the rest lexically by tostring().

You can then use it like this:

> t = {a=1, b=2, c=3, d=4, 'e', 'f', 'g', 'h'}
> for k,v in pairs(t) do print(k, v) end
1 e
2 f
3 g
4 h
a 1
d 4
c 3
b 2
> for k,v in sortedpairs(t) do print(k, v) end
1 e
2 f
3 g
4 h
a 1
b 2
c 3
d 4

Notice that pairs() returns the string keys in unsorted order.

```