Ruby Enumerable Magic: New Collections

  1. The Basics
  2. Unary Ampersand Operator
  3. Booleans
  4. Filters
  5. New Collections
  6. Aggregates

The Enumerable module offers several methods to create a new collection out of an existing one, by applying code to each item in the original collection.


This is the most common and straightforward method in the Enumerable module. It takes the original collection, applies the given block to each item within, and returns an array of the results:

irb(main):001:0> ['joshua', 'gabriel', 'jacob'].map{|name| name.capitalize}
=> ["Joshua", "Gabriel", "Jacob"]
irb(main):002:0> ['joshua', 'gabriel', 'jacob'].map(&:capitalize)
=> ["Joshua", "Gabriel", "Jacob"]

As with all Ruby methods that require a block, we can pass a block itself, or use the unary ampersand operator to pass a symbol that will be converted to a block and run on the object.


This method will return the same, unaltered items in the collection, but in a sorted order. It does this using each item’s <=> method. Objects like strings choose to be sorted alphabetically. Number classes choose to sort numerically. The important thing is that the items in the collection must have this method defined.

Now for an example:

irb(main):003:0> ['joshua', 'gabriel', 'jacob'].sort
=> ["gabriel", "jacob", "joshua"]
irb(main):004:0> [3, 1, 5].sort
=> [1, 3, 5]

You can also pass a block that will be used to sort items, if the default sort is not good enough. For instance, we could choose to sort strings alphabetically, but starting from last letter to first:

irb(main):005:0> ['joshua', 'gabriel', 'jacob'].sort{|a,b| a.reverse <=> b.reverse}
=> ["joshua", "jacob", "gabriel"]


A shorter way to sort based on the reversed version of strings like we did above, is to use the sort_by method, and passing either a block or using the unary ampersand operator to pass a symbol:

irb(main):007:0> ['joshua', 'gabriel', 'jacob'].sort_by{|name| name.reverse}=> ["joshua", "jacob", "gabriel"]
irb(main):008:0> ['joshua', 'gabriel', 'jacob'].sort_by(&:reverse)
=> ["joshua", "jacob", "gabriel"]

This is like calling map before calling sort. It will sort the results of the map method, not the collection items themselves.


Honestly, I haven’t found a good use case for this method, but I also didn’t know it existed until I did the research for this article. It has nothing to do with compression – a better name for it might have been “zipper”. Have you ever noticed on the highway when two lanes merge, a zipper effect is created? People instinctively take turns getting in line, much like the teeth of a zipper.

This method works in a similar fashion:

irb(main):010:0> [1, 2, 3].zip([4, 5, 6])
=> [[1, 4], [2, 5], [3, 6]]
irb(main):011:0> [1, 2, 3].zip([4, 5, 6], [7, 8, 9])
=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

It will take the original collection, and merge in the given array or arrays, as shown above. While I don’t yet know a great use case, I’ll keep my eyes peeled now that I understand how it works.


Tags: , , , , , , , , , ,

One Response to “Ruby Enumerable Magic: New Collections”

  1. Создание новых коллекций | Разработка на Ruby и Rails c нуля Says:

    […] Оригинал поста на английском: Ruby Enumerable Magic: New Collections […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: