1

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"}]
2
  • What is your code ht_new = ht.select {|hashes| arr.include? hashes} intended to stand for? Is it your failed attempt? Or are you claiming that it returns {"test": "abc", "testing": "fun"}, which is a lie, since a key-value pair is compared with arr, and furthermore, no key in ht matches arr unless you convert from string to symbol? Commented Jan 25, 2019 at 5:21
  • The second ht is not valid Ruby expression. Your second question is also not clear. Commented Jan 25, 2019 at 5:27

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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"}]

3 Comments

May be better to use reduce here because OP doesn't want the keys that aren't found in the array
@maxpleaner Thanks I see. I added a way to reject nil value. But I don't know how to with reduce?
Edit with an answer for the additional request
1

A straightforward way is:

 ht.slice(*arr.map(&:to_sym))
# => {:test => "abc", :testing => "fun"}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.