```On Oct 13, 12:46=A0am, Rahul Kumar <sentinel1... / gmail.com> wrote:
> I need to use *sort_by* to sort a table, since the user could select
> columns in any order.
>
> =A0 =A0 b=3D[ ["radio", 30, 5], ["radio", 20, 5], ["archie", 20, 5],
> ["newton", 10, 3] ]
> =A0 =A0 b.sort_by{|x| [ x[1], x[0] ]}
>
> Works fine. However, often the user will want a reverse sort on some
> field. I do not off-hand know the datatype of the field, but in most
> cases it will be a String.
>
> I tried:
>
> =A0 =A0 b.sort_by{|x| [ !x[1] ]}
> This works (one criteria), but this does not:
> =A0 =A0 b.sort_by{|x| [ !x[1], x[0] ]}
>
> Another thread here, suggested using a minus for Numbers but what about
> Strings.

Here is a solution that allows you to lazily evaluate keys and specify
that certain keys are to be reversed.

module Enumerable
def sort_by(*key_methods)
# allow for multiple key_methods and only
# evaluate them when they are truly needed
# for the sort
def compare(a,b, key_methods)
i =3D 0
while i < key_methods.size do
for elem in [a, b] do
fields =3D elem[0]
key =3D elem[1]
if fields.size <=3D i
fields[i] =3D key_methods[i][0].call(key)
end
end
if key_methods[i][1] =3D=3D :desc
a, b =3D b, a
end
result =3D (a[0][i] <=3D> b[0][i])
return result unless result =3D=3D 0
i +=3D 1
end
return result
end

self.collect do |item|
[ [], item ]
end.sort do |a, b|
compare(a, b, key_methods)
end.collect do |kv|
kv[1]
end
end
end

a =3D [