a tired guy
a tired guy

Reputation: 245

Ruby hash: return the first key value under which is not nil

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

Answers (3)

trunglee
trunglee

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

Sebastián Palma
Sebastián Palma

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 returns nil 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

set0gut1
set0gut1

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

Related Questions