Question
In Ruby or Rails, is there any real difference between calling map and collect on an array?
I found conflicting explanations online, and the official documentation seems to suggest they behave the same way. Are there any differences in behavior, implementation, or performance between these two methods?
For example:
numbers = [1, 2, 3]
result_with_map = numbers.map { |n| n * 2 }
result_with_collect = numbers.collect { |n| n * 2 }
Do these methods do the same thing, and is one preferred over the other in Ruby or Rails codebases?
Short Answer
By the end of this page, you will understand that map and collect in Ruby are effectively the same operation for transforming elements in an enumerable. You will learn how they work, why both names exist, whether there is any performance difference, which name is more common in real code, and how to use them correctly with examples.
Concept
In Ruby, map and collect are aliases for the same method on Enumerable.
That means:
- They perform the same job
- They produce the same result
- They have the same performance characteristics in normal Ruby usage
- Choosing one over the other is usually a matter of style and readability
What they do
Both methods iterate over a collection and return a new collection containing the result of running the block for each element.
[1, 2, 3].map { |n| n * 2 }
# => [2, 4, 6]
[1, 2, 3].collect { |n| n * 2 }
# => [2, 4, 6]
Why two names exist
Ruby often provides expressive method names that read well in different contexts.
mapis common in many programming languages and functional programmingcollectis an older, descriptive name that emphasizes gathering transformed results
Ruby keeps both names, but in modern Ruby code, map is generally more common.
Why this matters
Understanding aliases helps you:
- read older and newer Ruby code confidently
- avoid assuming two names mean two different behaviors
- follow style conventions in real projects
- write clearer transformation code
Important detail: non-destructive vs destructive versions
Both map and collect return a new array-like result and do not change the original collection.
Ruby also provides destructive versions:
map!collect!
These modify the original array in place.
numbers = [1, 2, 3]
numbers.map! { |n| n * 2 }
# numbers is now [2, 4, 6]
Mental Model
Think of a collection as a row of items on a conveyor belt.
eachmeans: look at each item one by onemaporcollectmeans: take each item, transform it, and place the transformed version into a new box
So if the original belt contains:
[1, 2, 3]
and your transformation is “multiply by 2”, the new box becomes:
[2, 4, 6]
map and collect are just two labels on the same machine. The machine itself works the same way either way.
Syntax and Examples
Core syntax
collection.map { |item| transformation }
collection.collect { |item| transformation }
Both return a new collection of transformed values.
Example 1: Transform numbers
numbers = [1, 2, 3, 4]
doubled = numbers.map { |n| n * 2 }
# => [2, 4, 6, 8]
also_doubled = numbers.collect { |n| n * 2 }
# => [2, 4, 6, 8]
Explanation:
- Ruby visits each number
- The block runs once per number
- The return value of the block is stored in a new array
Example 2: Transform strings
names = ["alice", "bob", "carol"]
capitalized = names.map { |name| name.capitalize }
# => ["Alice", "Bob", "Carol"]
Example 3: Shorthand with symbols
names = ["alice", "bob", "carol"]
capitalized = names.map(&:capitalize)
# => ["Alice", "Bob", "Carol"]
This is a shorter form commonly used when you want to call the same method on every element.
Example 4: Destructive version
numbers = [1, 2, 3]
numbers.collect! { |n| n + 10 }
# numbers is now [11, 12, 13]
Use map! or collect! only when you intentionally want to modify the original array.
Step by Step Execution
Consider this code:
numbers = [1, 2, 3]
result = numbers.map { |n| n * 3 }
Step by step:
numbersis assigned the array[1, 2, 3]- Ruby calls
mapon that array - Ruby takes the first element,
1, and assigns it ton - The block computes
1 * 3, which returns3 - Ruby stores
3in a new result array - Ruby takes the second element,
2, and assigns it ton - The block computes
2 * 3, which returns6 - Ruby stores
6in the result array - Ruby takes the third element,
3, and assigns it ton - The block computes
3 * 3, which returns9 - Ruby stores
9in the result array resultbecomes[3, 6, 9]- The original
numbersarray is still[1, 2, 3]
The same execution happens with collect:
numbers = [1, 2, 3]
result = numbers.collect { |n| n * 3 }
# => [3, 6, 9]
There is no behavioral difference in this normal case.
Real World Use Cases
Data transformation in apps
Convert raw values into display-ready values:
prices = [10, 20, 30]
formatted = prices.map { |price| "$#{price}" }
# => ["$10", "$20", "$30"]
Extracting attributes from model objects
In Rails applications, developers often transform objects into simpler values:
users = [OpenStruct.new(name: "Ava"), OpenStruct.new(name: "Noah")]
names = users.map(&:name)
# => ["Ava", "Noah"]
Preparing API responses
records = [{ id: 1, active: true }, { id: 2, active: false }]
ids = records.map { |record| record[:id] }
# => [1, 2]
Normalizing input data
emails = [" A@EXAMPLE.COM ", " B@EXAMPLE.COM "]
cleaned = emails.map { |email| email.strip.downcase }
# => ["a@example.com", "b@example.com"]
In all of these cases, map and collect would both work the same way.
Real Codebase Usage
In real Ruby codebases, developers usually prefer map over collect.
Why map is more common
- shorter and easier to scan
- common across many programming languages
- favored by many style guides and teams
- widely used in Ruby, Rails, and functional-style code
Common patterns
Transform after filtering
active_users = users.select(&:active?).map(&:email)
This means:
- keep only active users
- then extract their email addresses
Guard against nil
emails = users&.map(&:email) || []
This avoids errors if users is nil.
Prepare configuration or output data
payload = products.map do |product|
{
id: product.id,
name: product.name,
in_stock: product.in_stock?
}
end
In-place transformation when truly needed
tags.map!(&:downcase)
This changes the original array. Teams usually use this carefully because mutation can make code harder to reason about.
Practical advice
- Prefer
mapfor transformed output - Use
eachwhen you only want side effects - Use
map!only when mutation is intentional and safe - Be consistent with your team’s style
Common Mistakes
Mistake 1: Thinking map and collect are different
They are aliases in Ruby, so this assumption is incorrect.
[1, 2, 3].map { |n| n * 2 }
[1, 2, 3].collect { |n| n * 2 }
These do the same thing.
Mistake 2: Using map when you really want each
map is for building a new collection. If you only want a side effect, each is clearer.
Broken intention:
numbers = [1, 2, 3]
numbers.map { |n| puts n }
This prints the numbers, but it also creates a new array of block return values, which is usually unnecessary.
Better:
numbers.each { |n| puts n }
Mistake 3: Forgetting that map returns a new array
numbers = [1, 2, 3]
numbers.map { |n| n * 2 }
puts numbers.inspect
# => [1, 2, 3]
If you want the transformed result, assign it:
doubled = numbers.map { |n| n * 2 }
Or mutate intentionally:
numbers.map! { |n| n * 2 }
Mistake 4: Accidentally mutating when you did not mean to
names = ["Alice", "Bob"]
names.collect!(&:downcase)
# names is now changed
If you want to preserve the original array, use non-destructive map or collect.
Mistake 5: Expecting map to skip nil values
map transforms every element. It does not remove values by itself.
values = [1, nil, 3]
result = values.map { |v| v&.to_s }
# => ["1", nil, "3"]
If you want to remove elements, combine with compact or use filtering methods.
result = values.map { |v| v&.to_s }.compact
# => ["1", "3"]
Comparisons
map vs collect
| Method | Behavior | Return value | Performance | Common style |
|---|---|---|---|---|
map | Transforms each element | New collection | Same | More common |
collect | Transforms each element | New collection | Same | Less common |
map vs each
| Method | Main purpose | Returns | Best used for |
|---|---|---|---|
map | Transform data | New collection of transformed values | Building a new array |
each | Iterate through items | Original collection | Side effects like printing, logging, saving |
map vs map!
| Method | Changes original array? | Use when |
|---|---|---|
map | No | You want a new transformed result |
map! | Yes | You intentionally want to modify the existing array |
Practical takeaway
mapandcollectare equivalentmapandeachare not equivalentmap!andcollect!mutate the original array
Cheat Sheet
Quick facts
mapandcollectare aliases in Ruby- They behave the same way
- They have the same practical performance characteristics
- Both return a new collection
map!andcollect!modify the original array
Basic syntax
array.map { |item| ... }
array.collect { |item| ... }
Common examples
[1, 2, 3].map { |n| n * 2 }
# => [2, 4, 6]
[1, 2, 3].collect { |n| n * 2 }
# => [2, 4, 6]
Symbol-to-proc shorthand
names.map(&:upcase)
Destructive versions
array.map! { |item| ... }
array.collect! { |item| ... }
Use this rule
- Use
mapwhen you want transformed output - Use
eachwhen you only want side effects - Prefer
mapin most modern Ruby code
Watch out for
- forgetting to assign the result
- using
mapjust to print or log - using
map!when you do not want mutation
FAQ
Is map faster than collect in Ruby?
No. In normal Ruby usage, map and collect are aliases for the same behavior, so there is no meaningful difference to prefer one for speed.
Why does Ruby have both map and collect?
Ruby often provides multiple expressive method names. map is a common functional-programming term, while collect is a descriptive synonym.
Should I use map or collect in Ruby on Rails?
Most developers prefer map because it is shorter and more common in modern Ruby and Rails codebases.
Do map and collect change the original array?
No. Both return a new collection. If you want to modify the original array, use map! or collect!.
What is the difference between map and each in Ruby?
map builds a new collection from transformed values. each iterates for side effects and returns the original collection.
Can I use map on things other than arrays?
Yes. map is available through Enumerable, so many enumerable objects can use it, not just arrays.
Is collect deprecated in Ruby?
No. It still exists, but map is more commonly used in everyday Ruby code.
Mini Project
Description
Build a small Ruby script that transforms a list of user names into a cleaner format. This demonstrates how map is used in everyday data-cleaning tasks and reinforces that collect would behave the same way.
Goal
Create a script that takes an array of messy names, normalizes them, and produces a new array without changing the original array.
Requirements
- Start with an array of names that contain inconsistent capitalization and extra spaces.
- Use
mapto transform each name by trimming whitespace and capitalizing it. - Print both the original array and the transformed array.
- Show that the original array was not modified.
- Add a second example using
collectto prove it produces the same result.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.