Feature #12059
open`Array#single?`, `Hash#single?`
Description
There are some use cases when one wants to check if an array or a hash has exactly one element. I propose Array#single?
and Hash#single?
that checks for such cases and returns either true
or false
. This is an analogy from the empty?
method on the respective class.
- When creating an inflectional form out of an array:
a = ["object1", "object2"]
"There #{a.single ? "is" : "are"} #{a.length} #{a.single? ? "object" : "objects"}."
# => "There are 2 objects."
- When checking if all elements of the array are the same:
[1, 2, 2, 1].uniq.single? # => false
[1, 1, 1, 1].uniq.single? # => true
Updated by sikachu (Prem Sichanugrist) over 8 years ago
I feel like the usage of this method wouldn't be generic enough, and could be accomplished easily by .size.one?
Updated by mame (Yusuke Endoh) over 8 years ago
I'm neutral for the proposal itself. If it is accepted, I think "singleton?" is the best name.
In mathematics, a singleton ... is a set with exactly one element.
--
Yusuke Endoh mame@ruby-lang.org
Updated by danielpclark (Daniel P. Clark) over 8 years ago
Ruby currently supports the one?
method on both Hash and Array.
[1].one?
# => true
{a: 1}.one?
# => true
[1].method(:one?).owner
# => Enumerable
Updated by nobu (Nobuyoshi Nakada) over 8 years ago
[1, false, nil].one?
also returns true
.
From ri Enumerable#one?
:
enum.one? [{ |obj| block }] -> true or false
Passes each element of the collection to the given block. The method returns
true
if the block returns true exactly once. If the block is not given, one?
will return true only if exactly one of the collection members is true.
%w{ant bear cat}.one? { |word| word.length == 4 } #=> true
%w{ant bear cat}.one? { |word| word.length > 4 } #=> false
%w{ant bear cat}.one? { |word| word.length < 4 } #=> false
[ nil, true, 99 ].one? #=> false
[ nil, true, false ].one? #=> true
Updated by danielpclark (Daniel P. Clark) over 8 years ago
Right. Given the original examples by the OP Enumerable#one?
works.
a = ["object1", "object2"]
"There #{a.one? ? "is" : "are"} #{a.length} #{a.one? ? "object" : "objects"}."
# => "There are 2 objects."
[1, 2, 2, 1].uniq.one?
# => false
[1, 1, 1, 1].uniq.one?
# => true