Reputation: 245
Say I have a hash
hash = {a:1, b:false, c:nil}
& a series of keys somewhere: [:c, :b, :a]
. Is there a Ruby idiom for returning such a key value under which != nil?
The obv
[:c, :b, :a].select {|key| hash[key] != nil}.first # returns :b
seems too long.
Upvotes: 3
Views: 2371
Reputation: 11
You can use detect
this will return first value if match.
[:c, :b, :a].detect { |key| hash[key] != nill }
. This will return :b.
Hope to help you :D
Upvotes: 1
Reputation: 33420
For that I think Enumerable#find
might work:
find(ifnone = nil) { |obj| block } → obj or nil
find(ifnone = nil) → an_enumerator
Passes each entry in enum to block. Returns the first for which block is not false. If no object matches, calls
ifnone
and returns its result when it is specified, or returnsnil
otherwise.If no block is given, an enumerator is returned instead.
In your case it'd return the first for which block is not nil
:
p %i[c b a].find { |key| !{ a: 1, b: nil, c: nil }[key].nil? } # :a
p %i[c b a].find { |key| !{ a: 1, b: 1, c: nil }[key].nil? } # :b
Upvotes: 4
Reputation: 1672
If you want to filter elements with falsy values, you can use the following expressions.
keys = [:d, :c, :b, :a]
hash = { a: 1, b: nil, c: nil, d: 2 }
keys.select(&hash)
# => [:d, :a]
If you want to filter elements with exactly nil as a value, it is not correct, as Mr. Ilya wrote.
Upvotes: 3