New in Rails: Enumerable#group_by and Array#in_groups_of

Posted by marcel March 01, 2006 @ 08:35 PM

Changeset 3726 adds two little methods to ActiveSupport: Enumerable#group_by and Array#in_groups_of.

Enumerable#group_by is for collecting an enumerable into sets, grouped by the result of a block. Useful, for example, for grouping records by date.

     latest_transcripts.group_by(&:day).each do |day, transcripts| 
       p "#{day} -> #{transcripts.map(&:class) * ', '}" 
     end
     "2006-03-01 -> Transcript" 
     "2006-02-28 -> Transcript" 
     "2006-02-27 -> Transcript, Transcript" 
     "2006-02-26 -> Transcript, Transcript" 

Enumerable#group_by will be baked right into Ruby in the future, and currently lives in the 1.9 branch.

Array#in_groups_of let’s you iterate over an array in groups of a certain size, optionally padding any remaining slots with a specified value (nil by default).

     %w(1 2 3 4 5 6 7).in_groups_of(3) {|g| p g}
     ["1", "2", "3"]
     ["4", "5", "6"]
     ["7", nil, nil]

You gotta love the elegant encapsulation afforded by blocks! Yield.

Posted in Documentation, Tricks | 11 comments

Comments

  1. Adam Sanderson on 01 Mar 21:40:

    Thank you, a custom ‘group_by’ function seems to end up in every application I write.

    However isn’t ‘in_groups_of’ essentialy the same as ‘each_slice’ in the enumerator standard library? (minus the nil padding)

    .adam
  2. Marcel Molina Jr. on 01 Mar 22:00:

    If you take a look at the source, you’ll see that it wraps Enumerator#each_slice, adding padding if necessary. So, yes, it is each_slice plus padding.

  3. mico on 01 Mar 23:28:

    cool, i was just about to write something like this ;)

  4. namxam on 01 Mar 23:37:

    very nice, indeed. this is definitely something you use in almost every app.

  5. Jeem on 01 Mar 23:57:

    It’s a multimap; cool.

  6. Justin on 02 Mar 01:01:

    Some of the syntax is confusing me – what does the &:day argument in

    latest_transcripts.group_by(&:day)

    do? And the same for the &:class argument inside the block?

  7. Adam on 02 Mar 13:34:

    FYI,

    This post broke the entire weblog page in IE. Yeah yeah I know IE sucks but it should still be fixed.

  8. Joe on 02 Mar 19:54:

    Yeah, I’m confused by the syntax as well.

  9. undees on 02 Mar 20:05:

    In:

    latest_transcripts.group_by(&:day)

    I think the unfamiliar syntax means, “Call the method ‘day’ on each transcript.” The old-school way would look sort of like this:

    latest_transcripts.group_by {|transcript| transcript.day}

    More in Scott Raymond’s post.

  10. http://www.dewebtimes.com on 22 Mar 07:32:

    very nice

  11. De Web Times on 22 Mar 07:33:

    very nice