Enumerable#uniq
Array · Updated March 31, 2026 · Enumerable The uniq method returns a new array containing only the unique elements from a collection. Duplicates are removed based on equality (==), and the original order of elements is preserved — the first occurrence of each element is kept.
Basic Usage
Remove duplicates from an array of numbers:
numbers = [1, 2, 2, 3, 1, 4, 3, 5]
numbers.uniq
# => [1, 2, 3, 4, 5]
The returned array contains one occurrence of each unique value, in the order they first appeared.
With strings:
languages = ["ruby", "python", "ruby", "go", "python", "rust"]
languages.uniq
# => ["ruby", "python", "go", "rust"]
With a Block
Pass a block to determine uniqueness based on the block’s return value instead of the elements themselves:
words = ["apple", "apricot", "banana", "blueberry", "cherry"]
words.uniq { |word| word[0] }
# => ["apple", "banana", "cherry"]
The block evaluates word[0] for each element — "apple"[0] and "apricot"[0] both return "a", so only the first "a"-word survives. This is useful when you want uniqueness based on a specific attribute.
Practical Block Example: Unique by Attribute
Given a collection of objects, get one record per category:
products = [
{ name: "Laptop", category: "electronics" },
{ name: "Mouse", category: "electronics" },
{ name: "Carrot", category: "food" },
{ name: "Apple", category: "food" },
{ name: "Desk", category: "furniture" }
]
products.uniq { |p| p[:category] }
# => [{:name=>"Laptop", :category=>"electronics"},
# {:name=>"Carrot", :category=>"food"},
# {:name=>"Desk", :category=>"furniture"}]
Order Preservation
uniq preserves the original order of elements. The first occurrence of each unique element is kept:
[3, 1, 4, 1, 5, 9, 2, 6].uniq
# => [3, 1, 4, 5, 9, 2, 6]
This matters when order matters to your application — unlike some deduplication approaches that sort or randomize results.
Difference from & (Set Intersection)
Ruby has two ways to find unique or common elements. uniq removes duplicates from a single array, while & finds the intersection of two arrays:
a = [1, 2, 2, 3, 4]
b = [2, 3, 3, 5]
# uniq removes duplicates from ONE array
a.uniq
# => [1, 2, 3, 4]
# & finds elements present in BOTH arrays
a & b
# => [2, 3]
& requires two arrays and returns elements that exist in both. uniq operates on a single array and removes repeated elements.
When to Use Each
- Use
uniqwhen you want to deduplicate a single list - Use
&when you want to find common elements between two lists
# Deduplicate one list
["cat", "dog", "cat", "mouse"].uniq
# => ["cat", "dog", "mouse"]
# Find overlapping tags
user_tags = ["ruby", "rails", "postgres", "linux"]
post_tags = ["ruby", "python", "linux", "docker"]
user_tags & post_tags
# => ["ruby", "linux"]
Handling nil Values
nil is treated as a regular value and participates in uniqueness checking:
[1, nil, 2, nil, 3, nil].uniq
# => [1, nil, 2, 3]
One nil is kept along with one occurrence of each non-nil unique value.
With a block, nil block results work the same way:
data = [1, 2, 3, 4, 5]
data.uniq { |n| n.even? ? "even" : nil }
# => [1, 2]
The block returns nil for odd numbers. Since all odd numbers produce the same block result (nil), only the first odd number survives.
Uniq on Hashes
When called on a hash, uniq first converts the hash to an array of [key, value] pairs:
stock = { apples: 50, bananas: 30, oranges: 25, apples: 20 }
stock.uniq
# => [[:apples, 50], [:bananas, 30], [:oranges, 25], [:apples, 20]]
Note that Ruby’s hash literal syntax actually prevents duplicate keys — the last value for :apples (20) overwrites the first (50). But when working with arrays of pairs or enumerators over hashes, uniq is useful:
# Often used with to_a or to_enum
stock.to_a.uniq
# => [[:apples, 50], [:bananas, 30], [:oranges, 25], [:apples, 20]]
# Using to_enum explicitly
stock.to_enum.uniq
# => [[:apples, 50], [:bananas, 30], [:oranges, 25], [:apples, 20]]
Practical Examples
Removing Duplicate Names
attendees = ["Alice", "Bob", "Charlie", "Alice", "Diana", "Bob"]
attendees.uniq
# => ["Alice", "Bob", "Charlie", "Diana"]
Finding Unique Values by Attribute
users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "member" },
{ name: "Charlie", role: "admin" },
{ name: "Diana", role: "member" }
]
users.uniq { |u| u[:role] }
# => [{:name=>"Alice", :role=>"admin"},
# {:name=>"Bob", :role=>"member"}]
Counting Occurrences After uniq
Combine uniq with other methods to analyze data:
urls = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page1",
"https://example.com/page3",
"https://example.com/page2"
]
# How many unique pages were accessed?
urls.uniq.count
# => 3
# List the unique pages
urls.uniq
# => ["https://example.com/page1",
# "https://example.com/page2",
# "https://example.com/page3"]
Chaining with Other Enumerable Methods
scores = [100, 85, 100, 92, 85, 78, 100]
# Get unique passing scores, sorted
scores.select { |s| s >= 80 }.uniq.sort
# => [100, 85, 92, 78] → wait, let's trace this
scores.select { |s| s >= 80 }
# => [100, 85, 100, 92, 85, 100]
scores.select { |s| s >= 80 }.uniq
# => [100, 85, 92]
scores.select { |s| s >= 80 }.uniq.sort
# => [85, 92, 100]
Performance Notes
uniq iterates through the collection once and uses a hash internally to track seen elements. This gives it O(n) time complexity, where n is the collection size.
- Best for: collections with many duplicates, or when you need block-based uniqueness
- Alternative for small collections: if you only have two arrays and want common elements,
&is more explicit - Does not modify the original:
uniqreturns a new array and leaves the original unchanged
original = [1, 2, 2, 3]
deduped = original.uniq
original
# => [1, 2, 2, 3]
deduped
# => [1, 2, 3]
Return Value
uniq always returns an array, even when called on an enumerable with no duplicates:
[].uniq
# => []
[42].uniq
# => [42]
When given a block, the return type is still an array containing the original elements (not the block results):
[1, 2, 3].uniq { |n| n.even? }
# => [1, 2]
The block only determines uniqueness — the original elements are returned.
See Also
Enumerable#tally— count occurrences of each elementEnumerable#group_by— group elements by a shared attributeEnumerable#select— filter elements matching a condition