Question

Remove Duplicate Elements from an Array in Ruby

rubyruby-on-railsarraysduplicates

Question

I have a Ruby array that contains duplicate elements:

copy_array = [1, 2, 2, 1, 4, 4, 5, 6, 7, 8, 5, 6]

How can I remove the duplicate values from this array while keeping only unique elements, without writing explicit for loops or manual iteration?

Short Answer

By the end of this page, you will understand how Ruby removes duplicates from arrays using built-in methods such as uniq and uniq!. You will also learn when to use the non-destructive versus destructive version, what order Ruby keeps, and how this pattern is used in real code.

Concept

In Ruby, arrays often contain repeated values. Removing duplicates is a common task called deduplication.

Ruby provides built-in methods so you do not need to write your own loop for this. The most common method is:

array.uniq

This returns a new array containing each value only once.

For example:

[1, 2, 2, 1, 4].uniq
# => [1, 2, 4]

Ruby keeps the first occurrence of each value and removes later repeats.

This matters because deduplication appears often in real programs:

  • cleaning user input
  • removing repeated IDs from database results
  • processing tags or categories
  • preparing data before counting or grouping
  • avoiding duplicate work in scripts or APIs

Ruby's built-in methods are preferred because they are short, readable, and optimized compared with manually writing loops.

Mental Model

Think of uniq like a guest list at an event.

  • The first time a person's name appears, they are added to the list.
  • If the same name appears again later, it is ignored.
  • The final list contains each guest only once, in the order they first appeared.

So this:

[1, 2, 2, 1, 4, 4]

becomes:

[1, 2, 4]

because Ruby keeps the first 1, first 2, and first 4, then skips the repeats.

Take Quiz

Syntax and Examples

The main Ruby methods for removing duplicates from arrays are:

array.uniq   # returns a new deduplicated array
array.uniq!  # modifies the original array in place

Basic example

copy_array = [1, 2, 2, 1, 4, 4, 5, 6, 7, 8, 5, 6]
unique_values = copy_array.uniq

puts unique_values.inspect
# => [1, 2, 4, 5, 6, 7, 8]

copy_array stays unchanged because uniq returns a new array.

In-place example

copy_array = [1, 2, 2, 1, 4, 4, 5, 6, 7, 8, 5, 6]
copy_array.uniq!

puts copy_array.inspect
# => [1, 2, 4, 5, 6, 7, 8]

Here, the original array is modified.

Strings example

names = ["Ana", "Ben", "Ana", "Chris", "Ben"]
puts names.uniq.inspect
# => ["Ana", "Ben", "Chris"]

Important behavior: order is preserved

numbers = [3, 1, 3, 2, 1]
puts numbers.uniq.inspect
# => [3, 1, 2]

Ruby does not sort the array here. It keeps the first appearance order.

Step by Step Execution

Consider this code:

copy_array = [1, 2, 2, 1, 4, 4, 5]
result = copy_array.uniq

Step by step, Ruby effectively builds the result like this:

  1. Start with an empty result.
  2. Read 1 -> not seen before, keep it.
    • result: [1]
  3. Read 2 -> not seen before, keep it.
    • result: [1, 2]
  4. Read 2 again -> already seen, skip it.
    • result: [1, 2]
  5. Read 1 again -> already seen, skip it.
    • result: [1, 2]
  6. Read 4 -> not seen before, keep it.
    • result: [1, 2, 4]
  7. Read 4 again -> already seen, skip it.
    • result: [1, 2, 4]
  8. Read 5 -> not seen before, keep it.
    • result: [1, 2, 4, 5]

Final result:

[1, 2, 4, 5]

Original array:

[1, 2, 2, 1, 4, 4, 5]

If you used uniq, the original stays the same. If you used uniq!, the original would be changed.

Real World Use Cases

Removing duplicates from arrays is useful in many practical situations.

Cleaning form or API input

A user might submit repeated values:

tags = ["ruby", "api", "ruby", "backend"]
clean_tags = tags.uniq
# => ["ruby", "api", "backend"]

Preventing duplicate database IDs

user_ids = [12, 15, 12, 18, 15]
unique_user_ids = user_ids.uniq
# => [12, 15, 18]

Avoiding repeated work

If a job queue or script gets duplicate items, deduplication helps avoid processing the same item twice.

file_paths = ["a.txt", "b.txt", "a.txt"]
file_paths.uniq.each do |path|
  puts "Processing #{path}"
end

Building filter lists

categories = ["books", "games", "books", "music"]
menu_items = categories.uniq
# => ["books", "games", "music"]
Take Quiz

Real Codebase Usage

In real Ruby projects, uniq is often used as part of a data-cleaning pipeline.

Common pattern: sanitize then deduplicate

emails = ["a@example.com", "b@example.com", "a@example.com"]
clean_emails = emails.map(&:downcase).uniq

This normalizes values first, then removes duplicates.

Common pattern: deduplicate before querying

ids = params[:user_ids].uniq
users = User.where(id: ids)

This avoids unnecessary repeated IDs.

Common pattern: guard clauses with empty arrays

def fetch_users(ids)
  ids = ids.uniq
  return [] if ids.empty?

  User.where(id: ids)
end

Common pattern: combine arrays, then deduplicate

all_roles = default_roles + custom_roles
all_roles = all_roles.uniq

Destructive updates when mutation is intended

config[:hosts].uniq!

Developers use uniq! only when changing the original array is safe and expected.

Common Mistakes

1. Confusing uniq with uniq!

uniq returns a new array. uniq! changes the existing array.

numbers = [1, 1, 2]
numbers.uniq
puts numbers.inspect
# => [1, 1, 2]

Why? Because the result of uniq was not assigned.

Correct:

numbers = [1, 1, 2]
numbers = numbers.uniq
# or
numbers.uniq!

2. Expecting the result to be sorted

numbers = [3, 1, 3, 2, 1]
puts numbers.uniq.inspect
# => [3, 1, 2]

uniq removes duplicates, but it does not sort.

If you want both deduplication and sorting:

puts numbers.uniq.sort.inspect
# => [1, 2, 3]

3. Forgetting that uniq! can return nil

If no duplicates are removed, uniq! returns nil.

numbers = [1, 2, 3]
result = numbers.uniq!
puts result.inspect
# => nil

This can surprise beginners.

4. Using manual loops unnecessarily

Broken or overly verbose approach:

result = []
for item in copy_array
  result << item unless result.include?(item)
end

This works, but Ruby already provides a clearer built-in solution:

result = copy_array.uniq

5. Assuming different-looking values are duplicates

values = [1, "1", 1]
puts values.uniq.inspect
# => [1, "1"]

1 and "1" are different values and are not treated as duplicates.

Comparisons

ApproachChanges original array?Return valueBest use
array.uniqNoNew array with duplicates removedWhen you want to keep the original
array.uniq!YesModified array, or nil if unchangedWhen you intentionally want in-place modification
Manual loop + include?Usually noDepends on implementationRarely needed for basic deduplication
array.uniq.sortNoNew unique and sorted arrayWhen you need uniqueness and order sorted

uniq vs uniq!

arr = [1, 1, 2]
arr.uniq     # => [1, 2]
arr          # => [1, 1, 2]

arr.uniq!    # => [1, 2]
arr          # => [1, 2]

uniq vs sort.uniq

arr = [3, 1, 3, 2, 1]
arr.uniq      # => [3, 1, 2]
arr.sort.uniq # => [1, 2, 3]

Use uniq if you want to preserve first-seen order. Use sort.uniq if you want sorted output.

Take Quiz

Cheat Sheet

# Remove duplicates and return a new array
array.uniq

# Remove duplicates by modifying the original array
array.uniq!

Key rules

  • uniq does not modify the original array.
  • uniq! does modify the original array.
  • uniq preserves the order of first appearance.
  • uniq does not sort values.
  • uniq! returns nil if no changes were made.

Examples

[1, 2, 2, 1].uniq
# => [1, 2]

arr = [1, 1, 2]
arr.uniq!
# arr is now [1, 2]

Common combinations

array.uniq.sort     # unique then sorted
array.map(&:downcase).uniq
array.compact.uniq  # remove nil values, then duplicates

Watch out for

[1, "1", 1].uniq
# => [1, "1"]

Different types are not duplicates.

FAQ

How do I remove duplicates from an array in Ruby?

Use uniq:

array.uniq

It returns a new array with duplicates removed.

What is the difference between uniq and uniq! in Ruby?

uniq returns a new array. uniq! changes the original array in place.

Does Ruby uniq keep the original order?

Yes. Ruby keeps the first occurrence of each element and preserves that order.

Does uniq remove all repeated values from an array of strings?

Yes, as long as the strings are equal.

["a", "b", "a"].uniq
# => ["a", "b"]

Why does uniq! return nil sometimes?

If the array already has no duplicates, uniq! makes no change and returns nil.

Can I remove duplicates without writing a loop in Ruby?

Yes. uniq and uniq! are built-in methods, so you do not need to write an explicit loop yourself.

Can I sort the array after removing duplicates?

Yes:

array.uniq.sort
Take Quiz

Mini Project

Description

Build a small Ruby script that cleans a list of repeated email addresses before sending a newsletter. This demonstrates how deduplication prevents sending the same message multiple times.

Goal

Create a Ruby program that removes duplicate email addresses and prints the cleaned list.

Requirements

  • Store a list of email addresses in an array with some duplicates.
  • Remove duplicate email addresses using a built-in Ruby method.
  • Keep the original order of the first occurrence.
  • Print both the original array and the cleaned array.
Take Quiz

Keep learning

Related questions

View more