The old sorting ip addresses problem

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”]

On Tue, Jul 29, 2008 at 2:19 PM, matu [email protected] 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

Martin DeMello wrote:

thanks. this is much cleaner.

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

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