Natural order sort

split(/(\d+)/)

Interesting. I always assumed split filtered out the matching sections,
but it appears that you can make them appear in the resulting array by
putting brackets round the relevant bit in the regexp.

This isn’t mentioned in the Pragmatic Programmers book.

Sabby and Tabby wrote:

···

Alan Davies NOSPAMcs96and@yahoo.co.ukNOSPAM wrote:

I’ve written a natural order comparison funtion for the String class.
This was based on Martin Pool’s “Natural Order String Comparison” which
was written in C.
Natural Order String Comparison

The basic premise is that “something1” < “something2” < “something10”
which does not follow if you use alphabetical sorting.

I thought I’d post it here in case anyone was interested in it. I’d
also be grateful of any comments about improving it in any way.

Nifty and new in Ruby 1.8 is #sort_by:

def String.natural_order(nocase=false)
proc do |str|
i = true
str = str.upcase if nocase
str.gsub(/\s+/, ‘’).split(/(\d+)/).map {|x| (i = !i) ? x.to_i : x}
end
end

puts %w[ foo1 12 foo10 foo2 ].sort_by(&String.natural_order)

It is now :slight_smile:

···

On Monday, September 15, 2003, at 12:07 PM, Alan Davies wrote:

Interesting. I always assumed split filtered out the matching
sections, but it appears that you can make them appear in the
resulting array by putting brackets round the relevant bit in the
regexp.

This isn’t mentioned in the Pragmatic Programmers book.

Yup. That’s because it was modeled after the split function in
Perl, which behaves exactly the same way.

Given the relative paucity[1] of Ruby documentation, familiarity with
Perl can be a good way to set your behavioral expectations. Of course,
if it’s something you can test (as opposed to a feature which might or
might not occur to you at all), that’s the best way to determine the
behavior.

-Mark

[1] I did say “relative”. There’s just a heckuva lot more info out there
about Perl. The Ruby situation is steadily improving, however, and the
Pickaxe book is a wondrous thing. :slight_smile:

···

On Monday, September 15, 2003, at 12:07 PM, Alan Davies wrote:

Interesting. I always assumed split filtered out the matching
sections, but it appears that you can make them appear in the
resulting array by putting brackets round the relevant bit in the
regexp.