Array#intersection

Updated March 31, 2026 · Array Methods
ruby array intersection set stdlib

Array#intersection

The intersection method returns a new array containing elements that are present in all given arrays. It performs a set-like intersection while preserving duplicate elements from the first array.

Basic Usage

[1, 2, 3, 4].intersection([2, 4, 6])
# => [2, 4]

["a", "b", "c"].intersection(["b", "c", "d"])
# => ["b", "c"]

With Duplicates

Unlike a pure set operation, intersection preserves the multiplicity of elements from the first array:

[1, 1, 2, 2, 3].intersection([1, 2, 3])
# => [1, 1, 2, 2, 3]

[1, 1, 1].intersection([1, 2])
# => [1, 1, 1]

Multiple Arrays

You can pass multiple arrays to intersect more than two at once:

[1, 2, 3].intersection([2, 3, 4], [3, 4, 5])
# => [3]

The & Operator

The & operator is functionally identical to intersection. Use whichever reads better in your context:

[1, 2, 3] & [2, 3, 4]
# => [2, 3]

[1, 2, 3].intersection([2, 3, 4])
# => [2, 3]

Both produce the same result. intersection is more explicit, while & is more concise.

Intersection vs select + include

You can achieve similar results using select and include?, but the performance characteristics differ significantly:

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

# Using intersection — O(n)
a.intersection(b)
# => [3, 4]

# Using select + include — O(n * m)
a.select { |x| b.include?(x) }
# => [3, 4]

intersection uses a hash-based lookup under the hood, making it O(n + m) rather than O(n * m). For large arrays, the difference is substantial.

Practical Examples

Finding Common Tags

article_tags = ["ruby", "rails", "performance", "testing"]
user_interests = ["ruby", "javascript", "performance"]

article_tags.intersection(user_interests)
# => ["ruby", "performance"]

Shared Permissions

required_permissions = ["read", "write", "delete"]
user_permissions = ["read", "write"]

access_granted = required_permissions.intersection(user_permissions).size == required_permissions.size
# => false

Overlapping Schedules

available_monday = ["alice", "bob", "carol"]
available_wednesday = ["bob", "carol", "dave"]
available_friday = ["carol", "dave", "eve"]

["alice", "bob", "carol"].intersection(available_monday, available_wednesday, available_friday)
# => ["carol"]

Performance Notes

  • intersection is optimized for set-like operations and is significantly faster than equivalent select + include? chains on large arrays
  • Duplicate elements from the first array are preserved in the result
  • Elements from subsequent arrays do not affect the count — only their presence matters
  • The operation is order-preserving from the first array

See Also