[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

the old sorting ip addresses problem

matu

7/29/2008 9:19:00 PM

i am sure there has to be some ruby way of doing this in a really simple way...
i came up with this, but i am sure there is some other way that is much cleaner.

>> a = ["5.100.200.50", "10.150.50.1", "10.150.50.2", "10.150.51.1", "19.18.16.15", "192.168.0.1"]
=> ["5.100.200.50", "10.150.50.1", "10.150.50.2", "10.150.51.1", "19.18.16.15", "192.168.0.1"]
>> a.sort {|a1, a2| y = [a1, a2].map {|addr| x = 0; addr.split('.').reverse.each_with_index {|n, i| x = x + n.to_i * (256 ** (i))}; x}; y.last <=> y.first}
=> ["192.168.0.1", "19.18.16.15", "10.150.51.1", "10.150.50.2", "10.150.50.1", "5.100.200.50"]
>>


3 Answers

Martin DeMello

7/29/2008 9:26:00 PM

0

On Tue, Jul 29, 2008 at 2:19 PM, matu <m@t.u> wrote:
> i am sure there has to be some ruby way of doing this in a really simple way...
> i came up with this, but i am sure there is some other way that is much cleaner.
>
>>> a = ["5.100.200.50", "10.150.50.1", "10.150.50.2", "10.150.51.1", "19.18.16.15", "192.168.0.1"]
> => ["5.100.200.50", "10.150.50.1", "10.150.50.2", "10.150.51.1", "19.18.16.15", "192.168.0.1"]
>>> a.sort {|a1, a2| y = [a1, a2].map {|addr| x = 0; addr.split('.').reverse.each_with_index {|n, i| x = x + n.to_i * (256 ** (i))}; x}; y.last <=> y.first}
> => ["192.168.0.1", "19.18.16.15", "10.150.51.1", "10.150.50.2", "10.150.50.1", "5.100.200.50"]

a.sort_by {|x| x.split(/\./).map {|i| i.to_i}}.reverse

=> ["192.168.0.1", "19.18.16.15", "10.150.51.1", "10.150.50.2",
"10.150.50.1", "5.100.200.50"]

This relies on the fact that ruby has built-in array sorting, where
it'll sort by the first element, then break ties on the second
element, and so on, and a built-in sort_by function, that transforms a
collection according to the block given, and sorts by the transformed
values.

martin

matu

7/29/2008 9:32:00 PM

0

Martin DeMello wrote:

> a.sort_by {|x| x.split(/\./).map {|i| i.to_i}}.reverse
>
> => ["192.168.0.1", "19.18.16.15", "10.150.51.1", "10.150.50.2",
> "10.150.50.1", "5.100.200.50"]
>
> This relies on the fact that ruby has built-in array sorting, where
> it'll sort by the first element, then break ties on the second
> element, and so on, and a built-in sort_by function, that transforms a
> collection according to the block given, and sorts by the transformed
> values.
>

thanks. this is much cleaner.

Eric Hodel

7/31/2008 12:06:00 AM

0

On Jul 29, 2008, at 14:19 PM, matu wrote:

> i am sure there has to be some ruby way of doing this in a really
> simple way...
> i came up with this, but i am sure there is some other way that is
> much cleaner.
>
>>> a = ["5.100.200.50", "10.150.50.1", "10.150.50.2", "10.150.51.1",
>>> "19.18.16.15", "192.168.0.1"]
> => ["5.100.200.50", "10.150.50.1", "10.150.50.2", "10.150.51.1",
> "19.18.16.15", "192.168.0.1"]
>>> a.sort {|a1, a2| y = [a1, a2].map {|addr| x = 0;
>>> addr.split('.').reverse.each_with_index {|n, i| x = x + n.to_i *
>>> (256 ** (i))}; x}; y.last <=> y.first}
> => ["192.168.0.1", "19.18.16.15", "10.150.51.1", "10.150.50.2",
> "10.150.50.1", "5.100.200.50"]

$ ruby -ripaddr -e 'puts ["5.100.200.50", "10.150.50.1",
"10.150.50.2", "10.150.51.1", "19.18.16.15", "192.168.0.1"].
map { |ip| IPAddr.new ip }.sort_by { |ip| ip.hton }.join(", ")'
5.100.200.50, 10.150.50.1, 10.150.50.2, 10.150.51.1, 19.18.16.15,
192.168.0.1