lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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
      return tostring(a)<tostring(b)
    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.