From: Robert Klemme Date: 2009-05-19T15:15:03+09:00 Subject: Re: Sorting numbers as strings On 19.05.2009 02:55, Rob Biedenharn wrote: > 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 : $& } } > 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. Aaargh! Yes, you are completely right. > 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. Absolutely agree, I try to use local variables whenever possible. Although I recently learned that $1 etc. are local to the current stack frame! I did not knew that before and it certainly makes their use a lot safer. Thanks for catching my mistake! Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/