Alphanumeric Sort

I need to sort a collection of book models by their title. These are
technical books with long names including stuff like “Title 49, Parts
100-185”. My problem is that “Title 10” comes before “Title 2” because
strings are sorted left-to-right by character.

My fix is to define an instance method:

def alpha_name
name.split(/\W+/).collect{|p| p.match(/^\d+$/) ? p.to_i : p}.to_s
end

And in my controller:

@products.sort! { |a,b| a.alpha_name <=> b.alpha_name }

Is there a better (more optimized or more elegant) way to do this? Would
this sort of thing be useful in core?


Tim G.

Is there a better (more optimized or more elegant) way to do this? Would
this sort of thing be useful in core?
I’d say no, this sort of thing would not be useful (recommended) in
core. String based sorting is what it is (and is also affected by
language and locale). What you are doing is very specialized to your
application.

What I would do if it were my application is group the books into
volumes and chapters/parts. Then use these numeric attributes to
organize the book collections. Then you could have your database
perform your sorting, which would be much more efficient than do it
with array sorting.

I imagine for your specific case there would be three additional
attributes on your model [volume, begin_part, end_part]. Then :order
=> [ volume, begin_part ]. Then maybe use
“before_validation_on_create” to parse the book title and store the
three integer values in the database.