I have:
arr = ['test', 'testing', 'test123']
ht = {"test": "abc", "water": "wet", "testing": "fun"}
How can I select the values in ht
whose key matches arr
?
ht_new = ht.select {|hashes| arr.include? hashes}
ht_new # => "{"test": "abc", "testing": "fun"}"
Additionally, how can we return values from:
arr = ["abc", "123"]
ht = [{"key": "abc", "value": "test"}, {"key": "123", "value": "money"}, {"key": "doremi", "value": "rain"}}]
output # => [{"key": "abc", "value": "test"}, {"key": "123", "value": "money"}]
Only a slight change is needed:
ht.select { |k,_| arr.include? k.to_s }
##=> {:test=>"abc", :testing=>"fun"}
See Hash#select.
The block variable _
(a valid local variable), which is the value of key k
, signifies to the reader that it is not used in the block calculation. Some prefer writing that |k,_v|
, or some-such.
One option is mapping (Enumerable#map
) the keys in arr
:
arr.map.with_object({}) { |k, h| h[k] = ht[k.to_sym] }
#=> {"test"=>"abc", "testing"=>"fun", "test123"=>nil}
If you want to get rid of pairs with nil
value:
arr.map.with_object({}) { |k, h| h[k] = ht[k.to_sym] if ht[k.to_sym] }
#=> {"test"=>"abc", "testing"=>"fun"}
This is an option for the last request:
ht.select{ |h| h if h.values.any? { |v| arr.include? v} }
# or
arr.map { |e| ht.find { |h| h.values.any?{ |v| v == e } } }
#=> [{:key=>"abc", :value=>"test"}, {:key=>"123", :value=>"money"}]
A straightforward way is:
ht.slice(*arr.map(&:to_sym))
# => {:test => "abc", :testing => "fun"}