I have a list of TimeSheet objects from an ealier AR query, which I can sort by the full name of the user like so: @time_sheet_entries.sort! { |a,b| a.user.full_name <=> b.user.full_name } I can sort by the started time like so: @time_sheet_entries.sort! { |a,b| a.start_time <=> b.start_time } My question is how do I do a sort so that the list is sorted primarily by user.full_name but also by start_time? So that all the records for Joe Blogs are together but within those rather than being random it is then ordered by start_time? I know I could do it by putting some SQL on the original AR query but I''d like to know how to do it without doing that. FYI what is happening is: @time_sheet_entries.sort ... foreach entry in @time_sheet_entries ... print out that line in a table end I know that @time_sheet_entries.sort!{ |a,b| a.user.full_name <=> b.full_name }.sort!{ |a,b| a.start_time <=> b.start_time } won''t do the trick because assuming it is even valid Ruby it would just end up sorting by start_time. I thought that I could get a list of the users then do a foreach loop just picking up the users then iterating over them... (pseudo code so don''t expect this to actually work...) @time_sheet_entries.sort ... foreach user in @time_sheet_entries.unique(|x| x.user} foreach entry in @time_sheet_entries.select(|x| x.user = user} ... print out that line in a table end end but I think that''s quite lame. Surely there is a way to do it in one line? Any ideas anyone ? :-P -Rob -- ------------------------------------------------------ "On two occasions, I have been asked [by members of Parliament], ''Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?'' I am not able to rightly apprehend the kind of confusion of ideas that could provoke such a question." -- Charles Babbage (1791-1871) "98.5% of DNA is considered to be junk DNA with no known purpose. Maybe it''s XML tags." -- Anon http://www.robhulme.com/ http://robhu.livejournal.com/
On 7/26/06, Robert Hulme <rob@robhulme.com> wrote:> > I have a list of TimeSheet objects from an ealier AR query, which I > can sort by the full name of the user like so: > > @time_sheet_entries.sort! { |a,b| a.user.full_name <=> b.user.full_name } > > I can sort by the started time like so: > > @time_sheet_entries.sort! { |a,b| a.start_time <=> b.start_time } > > My question is how do I do a sort so that the list is sorted primarily > by user.full_name but also by start_time? So that all the records for > Joe Blogs are together but within those rather than being random it is > then ordered by start_time? > > I know I could do it by putting some SQL on the original AR query but > I''d like to know how to do it without doing that. > > FYI what is happening is: > > @time_sheet_entries.sort ... > foreach entry in @time_sheet_entries > ... print out that line in a table > end > > I know that > > @time_sheet_entries.sort!{ |a,b| a.user.full_name <=> b.full_name > }.sort!{ |a,b| a.start_time <=> b.start_time } > > won''t do the trick because assuming it is even valid Ruby it would > just end up sorting by start_time. I thought that I could get a list > of the users then do a foreach loop just picking up the users then > iterating over them... (pseudo code so don''t expect this to actually > work...) > > > @time_sheet_entries.sort ... > foreach user in @time_sheet_entries.unique(|x| x.user} > foreach entry in @time_sheet_entries.select(|x| x.user = user} > ... print out that line in a table > end > end > > but I think that''s quite lame. Surely there is a way to do it in one > line? Any ideas anyone ? :-P > > -Rob > -- > ------------------------------------------------------ > "On two occasions, I have been asked [by members of Parliament], > ''Pray, Mr. Babbage, if you put into the machine wrong figures, will > the right answers come out?'' I am not able to rightly apprehend the > kind of confusion of ideas that could provoke such a question." > -- Charles Babbage (1791-1871) > > "98.5% of DNA is considered to be junk DNA with no known purpose. > Maybe it''s XML tags." -- Anon > > http://www.robhulme.com/ > http://robhu.livejournal.com/ > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >You could sort it when you get it from the database. :order => ''field1, field2'' Alternatively, a pretty convoluted method tmp = @time_sheet_entries.group_by {&:full_name} @time_sheet_entries = tmp.keys.inject([]) do |arry, key| arry << tmp[key].sort_by{&:start_date} end -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060726/2218b5f8/attachment-0001.html
On Tuesday, July 25, 2006, at 5:48 PM, Robert Hulme wrote:>I have a list of TimeSheet objects from an ealier AR query, which I >can sort by the full name of the user like so: > >@time_sheet_entries.sort! { |a,b| a.user.full_name <=> b.user.full_name } > >I can sort by the started time like so: > >@time_sheet_entries.sort! { |a,b| a.start_time <=> b.start_time } > >My question is how do I do a sort so that the list is sorted primarily >by user.full_name but also by start_time? So that all the records for >Joe Blogs are together but within those rather than being random it is >then ordered by start_time? > >I know I could do it by putting some SQL on the original AR query but >I''d like to know how to do it without doing that. > >FYI what is happening is: > >@time_sheet_entries.sort ... >foreach entry in @time_sheet_entries > ... print out that line in a table >end > >I know that > >@time_sheet_entries.sort!{ |a,b| a.user.full_name <=> b.full_name >}.sort!{ |a,b| a.start_time <=> b.start_time } > >won''t do the trick because assuming it is even valid Ruby it would >just end up sorting by start_time. I thought that I could get a list >of the users then do a foreach loop just picking up the users then >iterating over them... (pseudo code so don''t expect this to actually >work...) > > >@time_sheet_entries.sort ... >foreach user in @time_sheet_entries.unique(|x| x.user} > foreach entry in @time_sheet_entries.select(|x| x.user = user} > ... print out that line in a table > end >end > >but I think that''s quite lame. Surely there is a way to do it in one >line? Any ideas anyone ? :-P > >-Rob >-- >------------------------------------------------------ >"On two occasions, I have been asked [by members of Parliament], >''Pray, Mr. Babbage, if you put into the machine wrong figures, will >the right answers come out?'' I am not able to rightly apprehend the >kind of confusion of ideas that could provoke such a question." >-- Charles Babbage (1791-1871) > >"98.5% of DNA is considered to be junk DNA with no known purpose. >Maybe it''s XML tags." -- Anon > >http://www.robhulme.com/ >http://robhu.livejournal.com/ >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/rails@time_sheet_entries.sort! do |a,b| n = a.user.full_name <=> b.user.full_name n == 0 ? a.start_time <=> b.start_time : n end The basic idea here is that the block for sort! should return a -1, 0, or 1 for the comparison. Just write code in there that will do that for the particular sort you want to do. In this case, if the names are equal, it compares the start_times. @time_sheet_entries = @time_sheet_entries.sort_by {|x| "#{x.user.full_name} #{x.start_time.to_i}" } This may also work. The key here is to add the second field in such a way that it sorts properly when displayed as a string. In this case, we just convert it to a numerical timestamp. To sort in decending time order, you could do this... @time_sheet_entries = @time_sheet_entries.sort_by {|x| "#{x.user.full_name} #{(Time.now - x.start_time).to_i}" } Warning: Untested YMMV. _Kevin www.sciwerks.com -- Posted with http://DevLists.com. Sign up and save your mailbox.
> @time_sheet_entries.sort! do |a,b| > n = a.user.full_name <=> b.user.full_name > n == 0 ? a.start_time <=> b.start_time : n > endThat''s brilliant :-) Thanks a lot. It works and more importantly makes sense to me when I read it :-)> @time_sheet_entries = @time_sheet_entries.sort_by {|x| > "#{x.user.full_name} #{x.start_time.to_i}" }I considered this but while 2000 > 100 isn''t it true that "100" > "2000". Going to an extra digit is not going to happen any time soon, but it seemed a bit hacky to me (when I originally considered this solution before my email to the RoR list). -Rob -- ------------------------------------------------------ "On two occasions, I have been asked [by members of Parliament], ''Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?'' I am not able to rightly apprehend the kind of confusion of ideas that could provoke such a question." -- Charles Babbage (1791-1871) "98.5% of DNA is considered to be junk DNA with no known purpose. Maybe it''s XML tags." -- Anon http://www.robhulme.com/ http://robhu.livejournal.com/
On Thursday, July 27, 2006, at 11:07 AM, Robert Hulme wrote:>> @time_sheet_entries.sort! do |a,b| >> n = a.user.full_name <=> b.user.full_name >> n == 0 ? a.start_time <=> b.start_time : n >> end >That''s brilliant :-) Thanks a lot. It works and more importantly makes >sense to me when I read it :-) > >> @time_sheet_entries = @time_sheet_entries.sort_by {|x| >> "#{x.user.full_name} #{x.start_time.to_i}" } >I considered this but while 2000 > 100 isn''t it true that "100" > >"2000". Going to an extra digit is not going to happen any time soon, >but it seemed a bit hacky to me (when I originally considered this >solution before my email to the RoR list). > >-Rob >-- >------------------------------------------------------ >"On two occasions, I have been asked [by members of Parliament], >''Pray, Mr. Babbage, if you put into the machine wrong figures, will >the right answers come out?'' I am not able to rightly apprehend the >kind of confusion of ideas that could provoke such a question." >-- Charles Babbage (1791-1871) > >"98.5% of DNA is considered to be junk DNA with no known purpose. >Maybe it''s XML tags." -- Anon > >http://www.robhulme.com/ >http://robhu.livejournal.com/ >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/railsYeah, it is a bit hacky. However, if you print out the time value as the unix timestamp and pad it with leading zeros, it will work. I prefer the first method myself. _Kevin www.sciwerks.com -- Posted with http://DevLists.com. Sign up and save your mailbox.