Hash # slice like method that returns nil if the given key is absent

I am using the method Hash#slice

in my rails environment.

slice

the method works like this:

{ a: 1, b: 2, d: 4 }.slice(:a, :c, :d)
=> {:a=>1, :d=>4}

      

But I want to return nil

if the given key is missing, for example:

{ a: 1, b: 2, d: 4 }.slice(:a, :c, :d)
=> {:a=>1, :c=>nil, :d=>4}

      

This is what I wrote for the function, is there a better way to write this function?

hash = {a: 1, b: 2, d: 4}
keys = [:a, :c, :d]
keys_not_present = keys.map { |key| key unless hash.has_key?(key) }.compact
keys_not_present = keys_not_present.zip([nil]*keys_not_present.size).to_h
hash.slice(*keys).merge(keys_not_present)

      

Hash order is irrelevant.

+3


source to share


3 answers


I would use the reduce

terms that interest you:



hash = {a: 1, b: 2, d: 4}
[:a, :c, :d].reduce({}) {|h, k| h[k] = hash[k]; h }

      

+2


source


Another option:

hash = {a: 1, b: 2, d: 4}
[:a, :c, :d].collect { |k| [k, hash[k]] }.to_h
 => {:a=>1, :c=>nil, :d=>4}

      



You can patch monkey Hash

add it as a method:

class Hash
  def my_slice(*keys)
    keys.collect { |k| [k, self[k]] }.to_h
  end
end

 {a: 1, b: 2, d: 4}.my_slice(:a, :c, :d)
 => {:a=>1, :c=>nil, :d=>4}

      

+1


source


Here's my solution; it creates a new hash from the array keys

with values nil

and concatenates that with the slice results:

> Hash[keys.zip].merge(hash.slice(*keys))
 => {:a=>1, :c=>nil, :d=>4}

      

+1


source







All Articles