Posted about 5 years 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:

module Enumerable def count_by(&block) list = group_by(&block) .map { |key, items| [key, items.count] } .sort_by(&:last) Hash[list] end end # Returns a Hash of { key => count } pairs (see below)

Just paste that snippet into a Rails console and use #count_by now!

Usage examples

  • Number of email addresses by domain:
> User.all.count_by { |user| /^.*@/, '' } => { ""=>2, ..., ""=>128, ""=>153}
  • 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: 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:

list .group_by { |item| } # Group .map { |key, items| [key, items.count] } # Count .select { |key, count| count > 10 } # Filter .sort_by(&:last) # Sort ASC .reverse # 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.

Your development team has a full backlog of feature requests, chores and refactoring coupled with deadlines? We are familiar with that. With our "DevOps as a Service" offering, we support developer teams with infrastructure and operations expertise.

Owner of this card:

Dominik Schöler
Last edit:
4 months 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 short-lived cookies to improve usability.
Accept or learn more