rubyguides

Array#one?

arr.one? { |element| block } -> true or false

one? is an Enumerable method that tests whether exactly one element in a collection matches a given condition. It returns true if precisely one element satisfies the criteria, otherwise false.

Syntax

array.one? { |element| block }

Without a block, it checks for truthy values. That distinction is important because the blockless form tests whether exactly one element is truthy in Ruby’s sense, not whether exactly one element meets a custom condition. When you want a specific test, always pass a block to make the rule explicit.

Parameters

ParameterTypeDefaultDescription
blockProcA condition to evaluate against each element

Examples

Basic usage

numbers = [1, 2, 3, 4, 5]

numbers.one? { |n| n == 3 }
# => true (exactly one element equals 3)

numbers.one? { |n| n > 4 }
# => false (two elements: 4 and 5)

The block form gives you precise control over what counts as a match. You can test for equality, a range, a type check, or any predicate that returns a boolean. The method stops scanning as soon as it finds a second match, so the cost stays low even for large collections where most elements fail the test.

Without a block

[0, 1, 2].one?
# => true (exactly one truthy value: 1)

[false, nil, 1].one?
# => true

[0, false, nil].one?
# => false (no truthy values)

When you call one? without a block, Ruby checks each element for truthiness using its own definition of what counts as true. That works well for simple existence checks, but it can surprise readers who expect 0 to be falsy the way it is in some other languages. In Ruby, only nil and false are falsy, so 0 passes the truthy test.

With pattern matching (Ruby 3.0+)

items = [1, "hello", :symbol, 3.14]

items.one?(String)
# => true (only one String element)

items.one?(Integer)
# => false (multiple integers)

Pattern matching with one? was added in Ruby 3.0 and works the same way as the block form but reads more like a type guard. Pass a class and Ruby checks each element with is_a? under the hood. You can also pass a regular expression to match against string elements, which is handy for quick format checks without writing a full block.

Errors

Empty arrays always return false:

[].one?
# => false

Performance Notes

one? stops after finding the second match, making it efficient for large datasets when you only need to know if there is exactly one match.

using one? for exact-count checks

one? is a nice fit when the code needs a small but precise answer: exactly one item should match, not zero and not many. That makes it useful for validation, light data checks, and situations where a single standout item matters. The method keeps the intent very clear, because the reader does not have to infer whether the logic is looking for one, many, or all. It says the rule directly and lets Ruby handle the counting.

That directness is helpful when the surrounding code wants to trigger a special case only if one value stands out from the rest. Instead of building a counter by hand, the method lets the caller state the condition in one place and move on. The result is easier to scan and easier to change later if the rule becomes more specific.

It is a nice fit for checks where a single match has special meaning, such as one selected option or one standout record in a small list. The method makes that rule explicit and keeps the surrounding branch from growing into a longer counting routine. When the reader can see the exact-count requirement in one line, the rest of the logic tends to stay calmer too.

Using one? with ranges

ages = [12, 17, 25, 30, 8]
ages.one? { |a| a < 13 }
# => true (only 12 and 8 are under 13? No — both are!)
# Wait: 12 < 13 is true, 8 < 13 is true → two matches → false
# => false

Range checks with one? are a practical pattern in validation code. You can test whether exactly one value falls within a given range, which is useful for confirming that a dataset has a single outlier or a single entry meeting a threshold.

See Also