Enumerable#first
Object | Array | nil · Updated March 31, 2026 · Enumerable What does first do?
first returns the first element of a collection, or the first n elements if an argument is provided. It is defined on Enumerable and works with arrays, ranges, hashes, and any other object that mixes in the Enumerable module.
When called without an argument on an empty collection, first returns nil. When called with an argument on an empty collection, it returns an empty array.
Basic Usage
Get the first element
[10, 20, 30, 40].first
# => 10
Works with ranges:
(1..10).first
# => 1
Get the first n elements
[10, 20, 30, 40, 50].first(3)
# => [10, 20, 30]
When called with an argument, first always returns an array — even if you ask for just one element:
[10, 20, 30].first(1)
# => [10]
This is different from calling first without arguments, which returns a single element or nil.
Empty Collections
first handles empty collections gracefully:
[].first
# => nil
[].first(3)
# => []
This behaviour makes first safe to call without checking whether the collection is empty first.
first(n) vs take(n)
first(n) and take(n) are similar but have important differences:
| Aspect | first(n) | take(n) |
|---|---|---|
| Defined on | Array only | Enumerable |
| Return type | Array | Array |
| On empty collection | [] | [] |
| Works with lazy enumerables | No | Yes |
# first is an Array method — converts enumerables to arrays first
(1..5).first(2)
# => [1, 2]
# take is Enumerable — works directly with lazy enumerables
(1..5).lazy.take(2).to_a
# => [1, 2]
The key practical difference: take is defined on Enumerable and works with lazy enumerators, while first is an Array method that eagerly evaluates its receiver.
The head Idiom
In functional programming traditions — and in some Ruby codebases — you may see head used to mean “first element”. Ruby doesn’t define a head method by default, but it is a common convention when working with lists or recursive data structures:
# A common pattern for extracting head and tail
head, *tail = [10, 20, 30, 40]
head # => 10
tail # => [20, 30, 40]
# This is functionally equivalent to:
[10, 20, 30, 40].first # => 10
Ruby’s built-in first is more explicit and idiomatic than the head convention.
Using with Enumerators
first works with enumerators created by other Enumerable methods:
# Create an enumerator by chaining methods
enum = [1, 2, 3, 4, 5].map.with_index
enum.first
# => [1, 0]
Enumerators are lazy by default, so combining first with enumerator methods can be efficient:
result = (1..1000).each_slice(10).first
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Practical Examples
Getting the first match
Use first after filtering with select or find to get the first matching result:
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
# Get first even number
numbers.select(&:odd?).first
# => 3
# Get first element greater than 5
numbers.find { |n| n > 5 }
# => 9
Getting the first n items
Often used with sort, group_by, or other Enumerable methods:
users = [
{ name: "Alice", score: 95 },
{ name: "Bob", score: 87 },
{ name: "Carol", score: 92 },
{ name: "Dave", score: 78 }
]
# Get top 3 performers
users.sort_by { |u| -u[:score] }.first(3)
# => [{ name: "Alice", score: 95 },
# { name: "Carol", score: 92 },
# { name: "Bob", score: 87 }]
first with find
Combine first with find for early termination in searches:
# Find the first user with a specific role, then get their name
users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "viewer" },
{ name: "Carol", role: "admin" }
]
users.find { |u| u[:role] == "admin" }[:name]
# => "Alice"
first with lazy
Use lazy to defer evaluation when working with large or infinite sequences:
# Get first 5 squares of even numbers
(1..).lazy \
.map { |n| n ** 2 } \
.select(&:even?) \
.first(5)
# => [4, 16, 36, 64, 100]
This is more efficient than evaluating the entire sequence before extracting results.
With hashes
first on a hash returns the first key-value pair as a two-element array:
{ a: 1, b: 2, c: 3 }.first
# => [:a, 1]
{ a: 1, b: 2, c: 3 }.first(2)
# => [[:a, 1], [:b, 2]]
Performance Notes
first is O(1) when called without arguments — it simply returns the first element without iteration.
When called with an argument first(n), it must collect n elements, making it O(n) in the size of n (not the collection). For very large n, consider whether you actually need all n elements upfront.
For lazy evaluation with large or infinite collections, prefer take with lazy:
# Eager — builds the entire array first
(1..1_000_000).first(10)
# Lazy — only evaluates what is needed
(1..1_000_000).lazy.first(10)
See Also
- /reference/enumerable/enumerable-take/ — Returns the first n elements as an array
- /reference/enumerable/enumerable-drop/ — Skips the first n elements and returns the rest
- /reference/enumerable/enumerable-find/ — Returns the first element that satisfies a condition