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 Gossett --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> 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. On Jul 30, 4:33 pm, "Tim Gossett" <timgoss...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> 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 Gossett--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Thu, Jul 31, 2008 at 10:47 AM, Robert Walker <r0b3rt4723-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote:> 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).Don''t numerals come before letters in all languages and locales?> What you are doing is very specialized to your application.I think it has usefulness in a number of situations. Has anyone else had to do something like this?> 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.That would work if all of the books in the database fit that model (title number and parts range). Most don''t, but a decent portion do. Others use volume numbers ("Vol. 1", "Vol. 2") or edition dates ("2008 Edition"). The question was if there''s a more efficient way to perform the sort. Being able to have the database do the sort would be great, but the database (MySQL 5.1) can''t split a string and sort the resulting array. Thanks, -- Tim --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---