Enumerable#max
Enumerable#max
The max method returns the largest element in an enumerable collection. It compares elements using the <=> operator (spaceship operator) to determine order.
Basic Usage
Without arguments, max returns the single largest element:
[3, 1, 4, 1, 5, 9, 2, 6].max
# => 9
["banana", "apple", "cherry"].max
# => "cherry"
Getting the N Largest Elements
Pass an integer n to get the n largest elements as an array:
[3, 1, 4, 1, 5, 9, 2, 6].max(3)
# => [9, 6, 5]
["banana", "apple", "cherry", "date"].max(2)
# => ["date", "cherry"]
Custom Comparison with a Block
You can provide a block to define custom comparison logic:
[-5, 3, -1, 7, -2].max { |a, b| a.abs <=> b.abs }
# => 7
["hello", "world", "ruby"].max { |a, b| a.length <=> b.length }
# => "hello"
The block must return -1, 0, or 1 (using the spaceship operator convention).
Handling Empty Collections
max returns nil when called on an empty collection:
[].max
# => nil
[].max(2)
# => []
max vs max_by
These two methods are often confused but behave differently:
| Method | What it compares |
|---|---|
max | Compares elements by their actual value using <=> |
max_by | Compares elements by the result of the block |
# max compares by value
[1, 2, 3].max
# => 3
# max_by compares by block result
["one", "two", "three"].max_by { |s| s.length }
# => "three"
Practical Examples
Finding the Highest Price
products = [
{ name: "Widget", price: 29.99 },
{ name: "Gadget", price: 49.99 },
{ name: "Doohickey", price: 19.99 }
]
expensive = products.max { |a, b| a[:price] <=> b[:price] }
expensive[:name]
# => "Gadget"
Finding the Longest String
words = ["elephant", "cat", "giraffe", "ant"]
longest = words.max { |a, b| a.length <=> b.length }
# => "giraffe"
Getting the N Most Expensive Items
products = [
{ name: "Widget", price: 29.99 },
{ name: "Gadget", price: 49.99 },
{ name: "Doohickey", price: 19.99 },
{ name: "Thingamajig", price: 39.99 }
]
products.max(2) { |a, b| a[:price] <=> b[:price] }
# => [{:name=>"Gadget", :price=>49.99}, {:name=>"Thingamajig", :price=>39.99}]
Working with Custom Objects
class Player
attr_reader :score
def initialize(name, score)
@name = name
@score = score
end
def <=>(other)
@score <=> other.score
end
def to_s
@name
end
end
players = [
Player.new("Alice", 95),
Player.new("Bob", 87),
Player.new("Charlie", 92)
]
players.max
# => Alice (score: 95)
Performance Notes
max uses the <=> operator to compare elements. For arrays, it performs a single pass through the collection — O(n) time complexity.
When using max with a block, the comparison logic runs multiple times during the sort. For finding a single maximum, max_by is often more efficient since it only evaluates the block once per element.
See Also
- /reference/enumerable/enumerable-min/ — returns the smallest element
- /reference/enumerable/enumerable-first/ — get the first element
- /reference/enumerable/enumerable-select/ — filter elements by condition