[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to sort a table in Ruby?

nkb

10/4/2004 8:17:00 AM

Hi.
I've a table with about 10 fields. I would like to be able to sort
ascending or decendingly, based on any one of the fields. I was
wondering if there might an elegant way to do this in Ruby? In C, I do
it by keeping track of the index of the array and then assigning them
individually. Thanks!!!


9 Answers

Brian Candler

10/4/2004 8:53:00 AM

0

On Mon, Oct 04, 2004 at 05:17:09PM +0900, nkb wrote:
> I've a table with about 10 fields. I would like to be able to sort
> ascending or decendingly, based on any one of the fields. I was
> wondering if there might an elegant way to do this in Ruby? In C, I do
> it by keeping track of the index of the array and then assigning them
> individually. Thanks!!!

Something like this?

a = [
[5,3,5,"foo"],
[2,1,9,"bar"],
[3,9,3,"baz"],
]
a.sort { |x,y| x[3] <=> y[3] } # sort on 4th element

You can get a reverse sort by

a.sort { |x,y| y[3] <=> x[3] }

Regards,

Brian.


Robert Klemme

10/4/2004 9:10:00 AM

0


"Brian Candler" <B.Candler@pobox.com> schrieb im Newsbeitrag
news:20041004085228.GA98486@uk.tiscali.com...
> On Mon, Oct 04, 2004 at 05:17:09PM +0900, nkb wrote:
> > I've a table with about 10 fields. I would like to be able to sort
> > ascending or decendingly, based on any one of the fields. I was
> > wondering if there might an elegant way to do this in Ruby? In C, I do
> > it by keeping track of the index of the array and then assigning them
> > individually. Thanks!!!
>
> Something like this?
>
> a = [
> [5,3,5,"foo"],
> [2,1,9,"bar"],
> [3,9,3,"baz"],
> ]
> a.sort { |x,y| x[3] <=> y[3] } # sort on 4th element
>
> You can get a reverse sort by
>
> a.sort { |x,y| y[3] <=> x[3] }

That's even better:

a.sort_by {|row| row[3]}

Regards

robert


Gavin Kistner

10/4/2004 1:04:00 PM

0

On Oct 4, 2004, at 3:14 AM, Robert Klemme wrote:
>> a.sort { |x,y| x[3] <=> y[3] } # sort on 4th element
> That's even better:
> a.sort_by {|row| row[3]}

The reason that #sort_by is better than #sort is described in the
documentation. In short (IIRC) it's because it caches the key values
for each row (performing the block only once for each row) and uses
those to sort, rather than invoking the block for every unique pair it
has to compare.

A downside, however, is the inability to specify something like a
reverse sort. (Although for that case you can just reverse the array
afterwards.)

Actually, does anyone have a compelling example where #sort produce a
result (which is reasonable) which #sort_by cannot? (By 'reasonable' I
mean that something like a.sort{ |x,y| x[3] <=> y[7] } does something
impossible for #sort_by, but probably would produce erratic results,
given no way of knowing in which order the pairs come.)



Robert Klemme

10/4/2004 1:57:00 PM

0


"Gavin Kistner" <gavin@refinery.com> schrieb im Newsbeitrag
news:E16B31E1-1605-11D9-AE46-000A959CF5AC@refinery.com...
> On Oct 4, 2004, at 3:14 AM, Robert Klemme wrote:
> >> a.sort { |x,y| x[3] <=> y[3] } # sort on 4th element
> > That's even better:
> > a.sort_by {|row| row[3]}
>
> The reason that #sort_by is better than #sort is described in the
> documentation. In short (IIRC) it's because it caches the key values
> for each row (performing the block only once for each row) and uses
> those to sort, rather than invoking the block for every unique pair it
> has to compare.

Yep. Plus, it's shorter to type, which was the main advantage I wanted to
point out here. :-)

> A downside, however, is the inability to specify something like a
> reverse sort. (Although for that case you can just reverse the array
> afterwards.)
>
> Actually, does anyone have a compelling example where #sort produce a
> result (which is reasonable) which #sort_by cannot? (By 'reasonable' I
> mean that something like a.sort{ |x,y| x[3] <=> y[7] } does something
> impossible for #sort_by, but probably would produce erratic results,
> given no way of knowing in which order the pairs come.)

The only one that I can think of at the moment is the one where there is
no proper comparision op defined. This is a made up example:

>> El = Struct.new(:foo, :bar)
=> El
>> El.new <=> El.new
NoMethodError: undefined method `<=>' for #<struct El foo=nil, bar=nil>
from (irb):3

Ok, no El.<=>() defined.

>> values = (1..10).map { El.new(rand(10), rand(10)) }
=> [#<struct El foo=6, bar=7>, #<struct El foo=5, bar=9>, #<struct El
foo=4, bar=8>, #<struct El foo=8, bar=9>, #<struct El foo=8, bar=7>,
#<struct El
foo=2, bar=2>, #<struct El foo=4, bar=5>, #<struct El foo=3, bar=5>,
#<struct El foo=8, bar=2>, #<struct El foo=1, bar=2>]

>> values.sort {|a,b| c = a.foo <=> b.foo; c == 0 ? a.bar <=> b.bar : c}
=> [#<struct El foo=1, bar=2>, #<struct El foo=2, bar=2>, #<struct El
foo=3, bar=5>, #<struct El foo=4, bar=5>, #<struct El foo=4, bar=8>,
#<struct El
foo=5, bar=9>, #<struct El foo=6, bar=7>, #<struct El foo=8, bar=2>,
#<struct El foo=8, bar=7>, #<struct El foo=8, bar=9>]

You can do this with sort_by but you have to create new instances (Arrays
in this case), which might or might not be acceptable depending on the
circumstances:

>> values.sort_by {|x| [x.foo, x.bar]}
=> [#<struct El foo=1, bar=2>, #<struct El foo=2, bar=2>, #<struct El
foo=3, bar=5>, #<struct El foo=4, bar=5>, #<struct El foo=4, bar=8>,
#<struct El
foo=5, bar=9>, #<struct El foo=6, bar=7>, #<struct El foo=8, bar=2>,
#<struct El foo=8, bar=7>, #<struct El foo=8, bar=9>]

I guess most real world cases can be covered by #sort_by.

Kind regards

robert

Florian Gross

10/4/2004 5:53:00 PM

0

Gavin Kistner wrote:

>>> a.sort { |x,y| x[3] <=> y[3] } # sort on 4th element
>> That's even better:
>> a.sort_by {|row| row[3]}
>
> The reason that #sort_by is better than #sort is described in the
> documentation. In short (IIRC) it's because it caches the key values for
> each row (performing the block only once for each row) and uses those to
> sort, rather than invoking the block for every unique pair it has to
> compare.
>
> A downside, however, is the inability to specify something like a
> reverse sort. (Although for that case you can just reverse the array
> afterwards.)

It is possible when you want to sort by something that can be expressed
as a number:

persons.sort_by { |person| -person.age }

Regards,
Florian Gross

Florian Frank

10/4/2004 6:25:00 PM

0

On 04.10.2004, at 15:04, Gavin Kistner wrote:
> The reason that #sort_by is better than #sort is described in the
> documentation. In short (IIRC) it's because it caches the key values
> for each row (performing the block only once for each row) and uses
> those to sort, rather than invoking the block for every unique pair it
> has to compare.

sort_by is only better if creating a temporary array of length n for
sort keys is faster than yielding the block or calling the <=> method
on elements ca. n*log(n) times. In theory this is always computational
faster but not necessarily on real machines that have to manage the
required memory. Using sort! instead of sort also can make a
difference.

The trade-off leans towards sort_by if the computations of the keys is
really slow (like accessing the filesystem or doing a dns-lookup) or if
comparing the computed keys is much faster than comparing the elements
directly. The last case can be used to speed up a sort by computing a
string of a complex object which can be compared more efficiently than
comparing the objects themselves. An interesting article on this topic
is "A Fresh Look at Efficient Perl Sorting" by Uri Guttman and Larry
Rosler, even if it's quite perl-centric:
http://www.sysarch.com/perl/sort_...

> A downside, however, is the inability to specify something like a
> reverse sort. (Although for that case you can just reverse the array
> afterwards.)

If your elements respond to a meaningful unary - you can do something
like
[1,3,4,2,5].sort_by { |x| -x }
for reverse sorting.

> Actually, does anyone have a compelling example where #sort produce a
> result (which is reasonable) which #sort_by cannot? (By 'reasonable' I
> mean that something like a.sort{ |x,y| x[3] <=> y[7] } does something
> impossible for #sort_by, but probably would produce erratic results,
> given no way of knowing in which order the pairs come.)

Well, you could always cheat like in this reverse sort example:

class Cheat < Struct.new(:a)
def <=>(other) other.a <=> a end
end

[1,3,4,2,5].sort_by { |x| Cheat.new(x) }

Florian Frank



Brian Candler

10/4/2004 6:33:00 PM

0

On Tue, Oct 05, 2004 at 03:25:19AM +0900, Florian Frank wrote:
> Using sort! instead of sort also can make a
> difference.

remembering that Array#sort is exactly Array#dup.sort! (as it the case with
many other methods, e.g. String#downcase is String#dup.downcase!)


Andy [Ex-MSFT]

10/1/2007 7:29:00 PM

0

See my post above, your video card is fine for this game razor.

"razor_303" <razor_303@earthlink.net> wrote in message
news:B3D7EDDC-E73E-4D26-9644-C9885EAC0176@microsoft.com...
> The installation took about 30 minutes, im thinking it DID copy all the
> 4.3something GB of data to my HD and yes the disk was in there all the
> time even after the installation was done and i tried running the game the
> first time, I thought it was zone alarm internet security blocking
> something but after i allowed everything from the disk to access the
> internet and etc, and unistalled and reinstall i knew it wasnt the
> problem.
>
> It appears my video card isnt supported, it does have 234 Mb to use which
> i thought would be enough to at least run halo 2 at minimum graphics
> options, but i guess not. i guess the games for windows game advisor isnt
> that accurate at telling you which games will run on your system.
>
> theres only one thing to do here and that is return the game, which isnt
> what i wanted because after playing halo 3 on the 360 i want to know what
> happened in halo 2...
>
> thanks everyone for your input
> "Paul Smith" <Paul@nospam.windowsresource.net> wrote in message
> news:0C7E013C-FA22-4F0F-AB81-8B0B5D4EEC03@microsoft.com...
>> "razor_303" <razor_303@earthlink.net> wrote in message
>> news:39DA6793-85AA-4B28-B9AF-6C88E395B630@microsoft.com...
>>>I just got Halo 2 for Windows Vista and installed it, I verified the key
>>>online and everything, and when i tried running it there was an error. It
>>>said there weren't sufficient resources to run the game or that some
>>>files were missing and to reinstall the game again.
>>
>> Did the game finish installing before you removed the disc from the
>> drive?
>>
>> --
>> Paul Smith,
>> Yeovil, UK.
>> Microsoft MVP Windows Shell/User.
>> http://www.dasmirnov...
>> http://www.windowsres...
>>
>> *Remove nospam. to reply by e-mail*
>>
>>
>

razor_303

10/2/2007 5:56:00 PM

0

i tried the installing the game in safe mode, all with the power cord
plugged in and my laptop at high performance, intel doesnt say whether halo2
works or not but they do have a list of games that will work with the
chipset/graphics of my laptop and im suprised some games like quake 4 wont
work on my machine even though it surpasses all the requirements maybe its
the same with halo 2. either way i already shipped the game back to the
online store for a full refund. i'll buy it again once i get a gaming
desktop pc

thanks

"Andy [YaYa]" <android8675@MAPSONhotmail.com> wrote in message
news:DF8B89E6-38D0-4C83-84CB-DF7BC8FB7198@microsoft.com...
> See my post above, your video card is fine for this game razor.
>
> "razor_303" <razor_303@earthlink.net> wrote in message
> news:B3D7EDDC-E73E-4D26-9644-C9885EAC0176@microsoft.com...
>> The installation took about 30 minutes, im thinking it DID copy all the
>> 4.3something GB of data to my HD and yes the disk was in there all the
>> time even after the installation was done and i tried running the game
>> the first time, I thought it was zone alarm internet security blocking
>> something but after i allowed everything from the disk to access the
>> internet and etc, and unistalled and reinstall i knew it wasnt the
>> problem.
>>
>> It appears my video card isnt supported, it does have 234 Mb to use which
>> i thought would be enough to at least run halo 2 at minimum graphics
>> options, but i guess not. i guess the games for windows game advisor isnt
>> that accurate at telling you which games will run on your system.
>>
>> theres only one thing to do here and that is return the game, which isnt
>> what i wanted because after playing halo 3 on the 360 i want to know what
>> happened in halo 2...
>>
>> thanks everyone for your input
>> "Paul Smith" <Paul@nospam.windowsresource.net> wrote in message
>> news:0C7E013C-FA22-4F0F-AB81-8B0B5D4EEC03@microsoft.com...
>>> "razor_303" <razor_303@earthlink.net> wrote in message
>>> news:39DA6793-85AA-4B28-B9AF-6C88E395B630@microsoft.com...
>>>>I just got Halo 2 for Windows Vista and installed it, I verified the key
>>>>online and everything, and when i tried running it there was an error.
>>>>It said there weren't sufficient resources to run the game or that some
>>>>files were missing and to reinstall the game again.
>>>
>>> Did the game finish installing before you removed the disc from the
>>> drive?
>>>
>>> --
>>> Paul Smith,
>>> Yeovil, UK.
>>> Microsoft MVP Windows Shell/User.
>>> http://www.dasmirnov...
>>> http://www.windowsres...
>>>
>>> *Remove nospam. to reply by e-mail*
>>>
>>>
>>
>