100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Ruby

each, map, and select

Master the three most commonly used Enumerable methods — each for side effects, map for transformation, and select for filtering — and when to reach for which.

Iterators & EnumerableBeginner8 min readJul 9, 2026
Analogies

each, map, and select

each, map, and select are the three Enumerable methods you'll reach for most often in everyday Ruby code, and understanding the distinct purpose of each is fundamental to writing idiomatic Ruby. each iterates purely for side effects and returns the original collection unchanged. map (aliased collect) transforms every element and returns a new array of the results. select (aliased filter) returns a new array containing only the elements for which the block returns a truthy value. Confusing these three is one of the most common mistakes new Ruby developers make.

🏏

Cricket analogy: A commentator narrating every ball bowled (each) is different from a scorer tallying each ball into a new highlights reel (map), which is different again from a selector filtering only the boundary-hitting balls (select) for a reel.

each: iteration for side effects

each is for when you want to do something with every element — print it, save it, send it somewhere — but don't need a new collection back. Critically, each always returns the original receiver, so chaining .map after .each operates on the original array, not on whatever the block returned.

🏏

Cricket analogy: A physio walking down the line checking every player's fitness doesn't hand back a new squad — they still work with the original eleven, just as each always returns the original receiver rather than a new collection.

ruby
users = ['Ada', 'Grace', 'Linus']

users.each { |name| puts "Hello, #{name}!" }
#=> prints 3 lines, returns ['Ada', 'Grace', 'Linus'] unchanged

map: transforming every element

map builds and returns a brand-new array where each element is the return value of the block applied to the corresponding original element. The original array is untouched (use the bang variant map! to mutate in place). This is the tool to reach for whenever you need 'the same collection, but every item changed somehow.'

🏏

Cricket analogy: Converting a list of raw ball-by-ball deliveries into a list of run totals per over is map — the original delivery list stays untouched, but a brand-new array of totals is built and returned.

ruby
prices = [10, 20, 30]
discounted = prices.map { |price| price * 0.9 }
#=> [9.0, 18.0, 27.0]
prices #=> [10, 20, 30] (unchanged)

select: filtering elements

select returns a new array containing only the elements for which the block returns something truthy, leaving the count of elements the same or smaller — unlike map, which always preserves the count but can change each value. Its logical opposite is reject, which keeps elements where the block is falsy.

🏏

Cricket analogy: Filtering a full over's deliveries down to only the boundaries hit is select — the resulting list can be the same size as the original over or smaller, while reject would keep only the non-boundary balls instead.

ruby
scores = [55, 82, 91, 40, 76]
passing = scores.select { |score| score >= 60 }
#=> [82, 91, 76]

failing = scores.reject { |score| score >= 60 }
#=> [55, 40]

In JavaScript, these map to forEach, map, and filter respectively — nearly identical semantics, which makes Ruby's Enumerable API feel familiar to JS developers. Python instead favors list comprehensions and generator expressions for map/filter-like transformations, with a built-in map() and filter() that return lazy iterators rather than arrays.

A very common bug: using each when you meant map. result = users.each { |u| u.upcase } returns the original, un-transformed users array, not the upcased names — the block's return value is discarded by each. If you need the transformed values, use map instead.

  • each iterates for side effects and always returns the original, unmodified collection.
  • map (alias collect) returns a new array built from the block's return values, one per element.
  • select (alias filter) returns a new array of elements where the block is truthy.
  • reject is select's inverse, keeping elements where the block is falsy.
  • Bang versions (map!, select!) mutate the receiver in place instead of returning a new array.
  • Using each when you actually need transformed output is a frequent beginner mistake.

Practice what you learned

Was this page helpful?

Topics covered

#Ruby#RubyStudyNotes#Programming#EachMapAndSelect#Each#Map#Select#Iteration#StudyNotes#SkillVeris