lua-users home
lua-l archive

Re: sorting non-numeric keys table with custom function ?

[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.

AltStyle によって変換されたページ (->オリジナル) /