Ruby—高效地将数据存储在深度嵌套的哈希中?
我正在编写一个脚本,它将数据库信息存储在一个散列中,以便以后访问。我的代码如下所示:Ruby—高效地将数据存储在深度嵌套的哈希中?,ruby,data-structures,performance,hashmap,Ruby,Data Structures,Performance,Hashmap,我正在编写一个脚本,它将数据库信息存储在一个散列中,以便以后访问。我的代码如下所示: my_hash = {} connection.query("select * from ...").each_hash do |row| date = row['date'] ip = row['ip'] port = row['port'] resp = row['avg_resp_time'].to_i unless my_hash.key?(ip) my_hash[i
my_hash = {}
connection.query("select * from ...").each_hash do |row|
date = row['date']
ip = row['ip']
port = row['port']
resp = row['avg_resp_time'].to_i
unless my_hash.key?(ip)
my_hash[ip] = { date => { port => resp } }
else
unless my_hash[ip].key?(date)
my_hash[ip][date] = { port => resp }
else
unless my_hash[ip][date].key?(port)
my_hash[ip][date][port] = resp
end
end
end
end
这只是一个示例,但实际的散列有时嵌套在5-6层的深处,并且需要很长时间才能构建一个大型结果集。我意识到在构建映射的时间和访问数据的时间之间有一个折衷,但我想知道是否有一种更有效的方法来存储数据,以便在代码中同样容易地访问,或者有一种方法可以使我当前的脚本更有效一点-这个哈希构建循环是我目前的瓶颈。谢谢。这方面的惯用Ruby是使用哈希构造函数来处理缺少的键:
>> data = Hash.new { |hash, key| hash[key] = {} }
>> data[:a][:b] = {:x => 5}
>> data
=> {:a=>{:b=>{:x=>5}}}
[编辑]我不确定您是否需要它,但上面的代码仅适用于一个嵌套级别。对于无限嵌套:
class Hash
def self.new_recursive
self.new { |hash, key| hash[key] = self.new_recursive }
end
end
data = Hash.new_recursive
....
但是,我倾向于不喜欢非函数式解决方案,因此您可能会选择Enumerable#group#U by,或者SQL级别的某种分组,即Enumerable#inject来构建嵌套哈希。只是一些原始的想法,这样你可以玩一点。这方面的惯用Ruby是使用哈希构造函数来处理缺少的键:
>> data = Hash.new { |hash, key| hash[key] = {} }
>> data[:a][:b] = {:x => 5}
>> data
=> {:a=>{:b=>{:x=>5}}}
[编辑]我不确定您是否需要它,但上面的代码仅适用于一个嵌套级别。对于无限嵌套:
class Hash
def self.new_recursive
self.new { |hash, key| hash[key] = self.new_recursive }
end
end
data = Hash.new_recursive
....
但是,我倾向于不喜欢非函数式解决方案,因此您可能会选择Enumerable#group#U by,或者SQL级别的某种分组,即Enumerable#inject来构建嵌套哈希。只是一些原始的想法,这样你可以玩一点。将数组指定为键怎么样?比如说
my_hash[[ip, date, port]] = resp
甚至
my_hash[[ip, date, port, resp]] = true
取决于你的目的。这将减少不必要的嵌套,并提高效率。将数组指定为键怎么样?比如说
my_hash[[ip, date, port]] = resp
甚至
my_hash[[ip, date, port, resp]] = true
取决于你的目的。这将减少不必要的嵌套,并提高效率。只要最大级别是固定的,这种方法是好的,但缺乏通用性。在您的示例中,您不能执行
数据[:a][:b][:x]=5
@sawa。的确如果需要多个级别:类Hash def self.recursive new{| Hash,key | Hash[key]=recursive}end endI see。看起来好多了。为什么不把它添加到你的答案中呢?这种方法是好的,只要最高级别是固定的,但它缺乏通用性。在您的示例中,您不能执行数据[:a][:b][:x]=5
@sawa。的确如果需要多个级别:类Hash def self.recursive new{| Hash,key | Hash[key]=recursive}end endI see。看起来好多了。为什么不把它加到你的答案里呢?