5

I have an array of keys:

keys = ["first_name", "last_name", "foo"]

and a hash:

hsh = {"first_name" => "tester", "zoo" => "loo", "foo" => "bar"}

I want to extract the key-value pairs whose keys are present in the array, to get:

res = {"first_name" => "tester", "foo" => "bar"}

Is there a way to do this?

sawa
  • 165,429
  • 45
  • 277
  • 381
harshs08
  • 700
  • 10
  • 29
  • Check [this](http://stackoverflow.com/questions/9025277/how-do-i-extract-a-sub-hash-from-a-hash) answer – mlovic Jul 06 '16 at 17:08
  • you could try slice like in [this](http://stackoverflow.com/questions/7430343/ruby-easiest-way-to-filter-hash-keys#25206082) answer. – AxelWass Jul 06 '16 at 17:08
  • @Зелёный I have tried the approach given by farhatmihalko and it works. Was looking for different or more ruby way to do this – harshs08 Jul 06 '16 at 21:44

5 Answers5

11
hsh.slice *keys
# => {"first_name" => "tester", "foo" => "bar"}
sawa
  • 165,429
  • 45
  • 277
  • 381
Fred Willmore
  • 4,386
  • 1
  • 27
  • 36
  • [map + each_with_object](https://github.com/rails/rails/blob/69db8dc468c16a961d0ee55384f97a1ccbe02da3/activesupport/lib/active_support/core_ext/hash/slice.rb#L21) – Roman Kiselenko Jul 06 '16 at 17:19
  • This is the way the go with Ruby >= 2.5.0 (Rails had this core extension earlier), no need for `.select{}`, `.reject{}` or `.keep_if{}` anymore. See [release notes](https://www.ruby-lang.org/en/news/2017/12/25/ruby-2-5-0-released/) – lxxxvi May 15 '18 at 08:51
6

Try this:

hsh.select{ |k, v| keys.include?(k) } 
sawa
  • 165,429
  • 45
  • 277
  • 381
Farkhat Mikhalko
  • 3,565
  • 3
  • 23
  • 37
2

It feels more natural to call keep_if instead of select:

hsh.keep_if { |key| keys.include? key }

Also, keep_if removes the unwanted pairs from the hash.

sawa
  • 165,429
  • 45
  • 277
  • 381
1

This is one approach:

hsh.select { |k,_| k.in?(keys) }
# => {"first_name" => "tester", "foo" => "bar"}

Note that although this is shorter than using include?, it depends on Rails being present.

sawa
  • 165,429
  • 45
  • 277
  • 381
Nic Nilov
  • 5,056
  • 2
  • 22
  • 37
0

You could use reject:

hsh.reject { |k| !keys.include? k } #=> {"first_name"=>"tester", "foo"=>"bar"}
Sagar Pandya
  • 9,323
  • 2
  • 24
  • 35