saihgala
saihgala

Reputation: 5774

Check if a given string exists as a key in nested hashes

Given a hash -

hash = { 
         1 => {"ID"         => ["NUMBER", 11]   }, 
         2 => {"TITLE"      => ["VARCHAR2", 5]  },
         3 => {"FIRST_NAME" => ["VARCHAR2", 50] }, 
         4 => {"LAST_NAME"  => ["VARCHAR2", 50] },         
         5 => {"BIRTH_DATE" => ["DATE", -2]     }
       }  

and 2 input parameters - "FIRST_NAME" and ["VARCHAR2",50].

What is the most elegant way to do -

  1. check whether "FIRST_NAME" exists as key of any nested hash.
  2. And if it exists whether value of hash[3]["FIRST_NAME"] is equal to second parameter i.e. ["VARCHAR2",50].
  3. And if these 2 parameters match then return the key whose value is this nested hash i.e. 3 in this case

Currently I do the following -

array = hash.values.map {|h| h.to_a}.flatten(2)
puts hash.key(Hash["FIRST_NAME",["VARCHAR2",50]]) if !(index = array.index("FIRST_NAME")).nil? ? array[index+1] == ["VARCHAR2",50] : false # 3

Upvotes: 1

Views: 2555

Answers (3)

Benoît
Benoît

Reputation: 15010

You will find a lot of information in you check the hash api.

a = 'FIRST_NAME'
b = ['VARCHAR2', 50]

hash.each do |k, v|
  if v.key?(a)            # ①
    return k if v[a] == b # ② and ③
  end
end

You could also write it as below actually because if it does not contain the key, it will never match and just go to the next occurence.

hash.each do |k, v|
  return k if v[a] == b
end

Your example only show hash with one pair, if there is more your need to do a new each on v.

Upvotes: 1

sawa
sawa

Reputation: 168269

There is a method key for doing just that:

hash.key({"FIRST_NAME" => ["VARCHAR2",50]}) # => 3

Upvotes: 1

Louis Ricci
Louis Ricci

Reputation: 21116

Seems like what your doing defeats the purpose/performance of a hash.

You should be using the (I assume) unique names "ID", "TITLE", "FIRST_NAME"... as your top level keys; the numbers 1-5 seem unused.

Searching a hash map by key is fast, having to map all values into an array than do a linear search on the array is slow.

Upvotes: 1

Related Questions