1

I have this hash and this array, and execute the following command...

hash={"a"=>1,"b"=>2,"c"=>3,"d"=>4,"e"=>5,"f"=>6}
array=["b","a","c","f","z","q"]
print hash.values_at(*array).compact

So I want it to return something like:

#=> [2,1,3,6,"invalid","invalid"]

Is there a way to declare all other elements non-existent in the hash as "invalid", without declaring one by one (e.g. "g"=>"invalid", "h"=>"invalid"...)?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Andre
  • 11
  • 1
  • 1
    yeah, just set `hash.default = "invalid"`. From [the docs](http://ruby-doc.org/core-2.0.0/Hash.html#method-i-default-3D) – Hamms Apr 18 '17 at 21:59
  • Possible duplicate of [Initializing hashes](http://stackoverflow.com/questions/2990812/initializing-hashes) – Brad Werth Apr 18 '17 at 22:17

3 Answers3

3

If a hash has to respond with a default value for a nonexistent key, then this value has to be set. Usually it is set on the initialization of the hash:

hash = Hash.new("invalid")

but it can be done anytime

hash={"a"=>1,"b"=>2,"c"=>3,"d"=>4,"e"=>5,"f"=>6}
array=["b","a","c","f","z","q"]

hash.default = "invalid"
p hash.values_at(*array)  #compact is superfluous

# => [2, 1, 3, 6, "invalid", "invalid"]
steenslag
  • 79,051
  • 16
  • 138
  • 171
3
array.map do |key|
  hash.fetch key, 'invalid'
end

if fetch is called with one argument, then if the key doesn't exist it will raise an error. However an optional second argument can set a custom return value for nonexistent keys.

The benefit of this over hash.default= or passing the default in the Hash constructor is that the hash itself is not changed, so if you lookup a nonexistent key in the future it will return nil as expected instead of 'invalid'.

max pleaner
  • 26,189
  • 9
  • 66
  • 118
  • Good explanation. Consider providing a link to the doc [Hash#fetch](http://ruby-doc.org/core-2.4.0/Hash.html#method-i-fetch). – Cary Swoveland Apr 18 '17 at 22:31
2

Try this:

array.map { |key|
    hash.has_key?(key) ? hash[key] : 'invalid'
}
AnoE
  • 8,048
  • 1
  • 21
  • 36