检查给定字符串是否作为嵌套哈希中的键存在

时间:2022-01-25 23:50:31

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].

和2个输入参数 - “FIRST_NAME”和[“VARCHAR2”,50]。

What is the most elegant way to do -

什么是最优雅的方式 -

  1. check whether "FIRST_NAME" exists as key of any nested hash.
  2. 检查“FIRST_NAME”是否作为任何嵌套哈希的键存在。

  3. And if it exists whether value of hash[3]["FIRST_NAME"] is equal to second parameter i.e. ["VARCHAR2",50].
  4. 并且如果它存在,则hash [3] [“FIRST_NAME”]的值是否等于第二参数,即[“VARCHAR2”,50]。

  5. And if these 2 parameters match then return the key whose value is this nested hash i.e. 3 in this case
  6. 如果这两个参数匹配,则返回其值为此嵌套散列的键,在这种情况下为3

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

3 个解决方案

#1


1  

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

你会发现很多信息都在检查哈希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.

您的示例仅显示具有一对的哈希,如果您需要在v上执行新的更多操作。

#2


1  

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.

您应该使用(我假设的)唯一名称“ID”,“TITLE”,“FIRST_NAME”...作为您的*键;数字1-5似乎未使用。

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.

按键搜索哈希映射很快,必须将所有值映射到数组中,而不是对阵列上的线性搜索进行缓慢。

#3


1  

There is a method key for doing just that:

有一个方法键可以做到这一点:

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

#1


1  

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

你会发现很多信息都在检查哈希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.

您的示例仅显示具有一对的哈希,如果您需要在v上执行新的更多操作。

#2


1  

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.

您应该使用(我假设的)唯一名称“ID”,“TITLE”,“FIRST_NAME”...作为您的*键;数字1-5似乎未使用。

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.

按键搜索哈希映射很快,必须将所有值映射到数组中,而不是对阵列上的线性搜索进行缓慢。

#3


1  

There is a method key for doing just that:

有一个方法键可以做到这一点:

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