rubyguides

Array#union

The union method returns a new collection containing all elements from the receiver and any additional lists passed as arguments. Duplicates are removed, with the first occurrence of each element preserved. The order of elements follows their first appearance across all arrays.

That makes union useful when you want to merge lists without creating repeated entries. It reads like set-style combination, but it still returns an array, so you keep the familiar array ordering rules.

Ruby also provides the | operator as a convenient alternative syntax for union operations between two arrays.

Syntax

array | other_array
array.union(*other_arrays)

The | operator works with exactly two lists, while the union method accepts multiple collections as arguments.

Parameters

ParameterTypeDefaultDescription
*other_arraysArrayArrays to combine with self (method form only)

The | operator does not accept parameters—it always operates on exactly two arrays.

Examples

Basic usage with the | operator

a = [1, 2, 3, 4]
b = [3, 4, 5, 6]

a | b
# => [1, 2, 3, 4, 5, 6]

The | operator is the most concise way to combine two arrays while removing duplicates. It reads like set notation, which makes the intent clear even to developers unfamiliar with Ruby’s array methods. The result preserves the order of first occurrence, so elements from a appear before new elements from b.

Using the method form with multiple arrays

a = [0, 1, 2, 3]
b = [4, 5]
c = [6, 7]

a.union(b, c)
# => [0, 1, 2, 3, 4, 5, 6, 7]

When you need to merge three or more lists, the method form reads more naturally than chaining the | operator multiple times. Each argument contributes its unique elements to the result, and the variadic signature makes the call site explicit about how many sources are being combined.

Handling duplicate values

a = [0, 1, 1]
b = [2, 1]

a.union(b)
# => [0, 1, 2]

Notice that the duplicate 1 appears only once in the result—the first occurrence is preserved. This is the key contract of union: each element appears exactly once in the output, at the position of its earliest encounter across all input arrays. If the same value shows up in multiple sources, the first one wins.

Preserving order

a = [3, 2, 1, 0]
b = [5, 3]
c = [4, 2]

a.union(b, c)
# => [3, 2, 1, 0, 5, 4]

The order reflects where each element first appeared: 3 and 0 from a, 5 first appears in b, and 4 first appears in c. This predictability makes union a reliable choice when the sequence of the output matters as much as the set of unique values it contains.

With no arguments

a = [1, 2, 3]

a.union
# => [1, 2, 3]

When called without arguments, union simply returns a copy of the receiver with duplicates removed. This is effectively a uniq-like operation that produces a fresh array. It is a safe default that lets you call the method uniformly even when the arguments list might be empty.

Common patterns

Combining unique tags

post1_tags = ["ruby", "rails", "tutorial"]
post2_tags = ["ruby", "performance", "rails"]
post3_tags = ["tutorial", "beginners"]

all_tags = post1_tags | post2_tags | post3_tags
# => ["ruby", "rails", "tutorial", "performance", "beginners"]

Chaining the | operator is a natural way to collect unique tags from multiple sources. Each | operation merges two lists and removes duplicates, and the final result contains every distinct tag from all three sources in the order they were first encountered.

Building a whitelist

allowed_categories = ["news", "sports", "tech"]
user_selections = ["news", "entertainment", "sports", "tech", "news"]

allowed_categories | user_selections
# => ["news", "sports", "tech", "entertainment"]

Performance notes

The union method uses a hash-based implementation for efficiency. When combining large arrays, this approach avoids the quadratic complexity you’d get from manually checking for duplicates.

That implementation detail matters most when the arrays are large or when you are unioning many lists in a row. In those cases, the built-in method is easier to read and usually faster than a hand-rolled loop.

The | operator is slightly faster for two-array operations since it doesn’t need to handle the variadic argument parsing.

See Also