From: Rob Biedenharn Date: 2009-05-19T09:55:12+09:00 Subject: Re: Sorting numbers as strings On May 18, 2009, at 1:01 PM, Robert Klemme wrote: > On 18.05.2009 17:37, Rob Biedenharn wrote: > >> If you do need to consider things like "FastEthernet..." v. >> "GigabitEthernet...", then perhaps you want something like this >> which breaks the original string into digits and non-digits and >> converts the digits to be integers. >> puts DATA.sort_by {|s| s.scan(/\d+|\D+/).map {|x| x =~ /\d+/ ? >> x.to_i : x } } > > Good point! Here's an interesting variant: > > puts DATA.sort_by {|s| s.scan(/(\d+)|\D+/).map { $1 ? $1.to_i : $& } } > > Kind regards > > robert > -- > remember.guy do |as, often| as.you_can - without end > http://blog.rubybestpractices.com/ Interesting, but "wrong" in that it doesn't sort the way the OP wanted. Actually, since all the regexp applications have been applied by #scan before the #map happens, the values of $1 and $& are effectively constants and no sorting happens at all. However, that did inspire me to make my version a little better. puts DATA.sort_by {|s| s.scan(/(\d+)|(\D+)/).map {|(n,s)| s || n.to_i } } I'd rather make the variables local than invoke the Perlish Regexp globals (even if they did were assigned in the block the way you expected). It could be even more readable if (n,s) were replaced with (digits,nondigits), but it looks OK to me with n and s. -Rob Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com