Posted about 1 year ago. Visible to the public.

Custom Ruby method Enumerable#count_by (use for quick statistics)

I frequently find myself needing a combination of group_by, count and sort for quick statistics. Here's a method on Enumerable that combines the three:

Copy
module Enumerable def count_by(&block) list = group_by(&block) .map{ |key, items| [key, items.count] } .sort_by(&:last) Hash[list] end end

The new method returns a Hash of key => count pairs.

Usage examples

Number of email addresses by domain:

Copy
> User.all.count_by { |user| user.email.sub /^.*@/, '' } => { "sina.cn"=>2, ..., "yahoo.cn"=>63, "hotmail.com"=>128, "gmail.com"=>153}

Others:

  • Number of new users per day: User.all.count_by { |user| user.created_at.to_date }
  • Number of articles per brand: Article.all.count_by &:brand

Note that the last simple example can also be achieved with Rails internals: Article.group(:brand).count. This translates to SQL, so it executes fast. However, grouping is restricted to columns (attributes). Using #count_by gives you the full flexibility of Ruby.

More tools

If you need further options, here's a "toolbox" of chainable method invocations:

Copy
list .group_by{ |item| item.id } # Group .map{ |key, items| [key, items.count] } # Count .select{ |key, count| count > 10 } # Filter .sort_by(&:last) # Sort ASC .sort_by{ |key, count| -count } # Sort DESC .each{ |key, count| puts "#{count.to_s.rjust(6)} #{key}" } # Print

Wrap the result in Hash[...] to turn a list-of-pairs into a Hash.

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for old versions of Ruby on Rails (3.2 and 2.3).

Owner of this card:

Avatar
Dominik Schöler
Last edit:
about 1 year ago
by Dominik Schöler
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Dominik Schöler to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more