I would like to count the number of users created each day. The problem arises that on some days no users a created so there are gaps in my array of users created by day. E.g. [ [''14 Jan'', 2], [''15 Jan'', 4], [''17 Jan'', 2] ] # [day, users created] I''ve written the following code which successfully works but I''m wondering if it can be done better as I am also wanting to sort users by month. So first: can it be written better Second(if you''ve got time) : how would you write to get users created in a month ------ data=[] start_date = Date.today-1month end_date = Date.today results = User.find(:all,:select => ''created_at'', conditions {:created_at => start_date..end_date}).group_by{|u| u.created_at.to_date}.sort #go through each date between start and end date and add 0 for missing days start_date.upto(end_date) do |date| result = results.find{|r| r[0]==date} users_count = result.nil? ? 0 : result[1].count data << [date.strftime("%d %b"), users_count] end ----- -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Rob Biedenharn
2011-Jan-04 01:52 UTC
Re: adding missing days to array of users created by day
On Jan 3, 2011, at 7:32 PM, Dandan wrote:> I would like to count the number of users created each day. The > problem arises that on some days no users a created so there are gaps > in my array of users created by day. E.g. > > [ [''14 Jan'', 2], [''15 Jan'', 4], [''17 Jan'', 2] ] # [day, users created] > > I''ve written the following code which successfully works but I''m > wondering if it can be done better as I am also wanting to sort users > by month. > So first: can it be written better > Second(if you''ve got time) : how would you write to get users created > in a month > ------ > data=[] > start_date = Date.today-1month > end_date = Date.today > > results = User.find(:all,:select => ''created_at'', conditions > {:created_at => start_date..end_date}).group_by{|u| > u.created_at.to_date}.sort > > #go through each date between start and end date and add 0 for missing > days > start_date.upto(end_date) do |date| > result = results.find{|r| r[0]==date} > users_count = result.nil? ? 0 : result[1].count > data << [date.strftime("%d %b"), users_count] > end > -----First, let me fake your results. Note that this does not bother to .sort since the .group_by will be a hash and that''s just as easy to work with. on14th = Date.civil(2011, 1, 14) on15th = Date.civil(2011, 1, 15) on17th = Date.civil(2011, 1, 17) results = [ on17th, on15th, on14th, on15th, on17th, on15th, on14th, on15th, ].group_by{|u| u} Use the << method of a Date to go back a month: end_date = Date.civil(2011,2,1) start_date = end_date << 1 Get the set of dates the simplest way possible. (Note that for large ranges this may be less practical.) date_range = (start_date .. end_date).to_a Then just map that range to the results you want. data = date_range.map {|d| [d.strftime("%d %b"), results.fetch(d, []).size] } You might also just get the counts from the database directly: results = User.find(:all, :select => ''DATE(created_at) as create_date, COUNT(*) as user_count'', :conditions => { :created_at => start_date..end_date }, :group => ''DATE(created_at)''). map{|u| [Date.parse(u.create_date), u.user_count.to_i]} data = date_range.map {|d| [d.strftime("%d %b"), (results.assoc(d) || [nil,0])[1]] } -Rob Rob Biedenharn Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org http://AgileConsultingLLC.com/ rab-/VpnD74mH8+00s0LW7PaslaTQe2KTcn/@public.gmane.org http://GaslightSoftware.com/ -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Marnen Laibow-Koser
2011-Jan-04 15:57 UTC
Re: adding missing days to array of users created by day
Rob Biedenharn wrote in post #972151: [...]> You might also just get the counts from the database directly: > results = User.find(:all, > :select => ''DATE(created_at) as create_date, COUNT(*) as > user_count'', > :conditions => { :created_at => start_date..end_date }, > :group => ''DATE(created_at)''). > map{|u| [Date.parse(u.create_date), u.user_count.to_i]} > data = date_range.map {|d| [d.strftime("%d %b"), > (results.assoc(d) || [nil,0])[1]] }Or better yet, use User.count instead of .find .> > -Rob > > Rob Biedenharn > Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org http://AgileConsultingLLC.com/ > rab-/VpnD74mH8+00s0LW7PaslaTQe2KTcn/@public.gmane.org http://GaslightSoftware.com/Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Rob Biedenharn
2011-Jan-04 17:06 UTC
Re: Re: adding missing days to array of users created by day
On Jan 4, 2011, at 10:57 AM, Marnen Laibow-Koser wrote:> Rob Biedenharn wrote in post #972151: > [...] >> You might also just get the counts from the database directly: >> results = User.find(:all, >> :select => ''DATE(created_at) as create_date, COUNT(*) as >> user_count'', >> :conditions => { :created_at => start_date..end_date }, >> :group => ''DATE(created_at)''). >> map{|u| [Date.parse(u.create_date), u.user_count.to_i]} >> data = date_range.map {|d| [d.strftime("%d %b"), >> (results.assoc(d) || [nil,0])[1]] } > > Or better yet, use User.count instead of .find .But the OP wanted counts by day, not a single total. -Rob> >> >> -Rob >> >> Rob Biedenharn >> Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org http://AgileConsultingLLC.com/ >> rab-/VpnD74mH8+00s0LW7PaslaTQe2KTcn/@public.gmane.org http://GaslightSoftware.com/ > > Best, > -- > Marnen Laibow-Koser > http://www.marnen.org > marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org > > ---- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Marnen Laibow-Koser
2011-Jan-04 17:16 UTC
Re: Re: adding missing days to array of users created by day
Rob Biedenharn wrote in post #972262:> On Jan 4, 2011, at 10:57 AM, Marnen Laibow-Koser wrote: > >>> (results.assoc(d) || [nil,0])[1]] } >> >> Or better yet, use User.count instead of .find . > > But the OP wanted counts by day, not a single total.Right. That''s what count with :group is for.> > -RobBest, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.