我正在写一个脚本,该脚本将数据库信息存储在一个散列中,以便以后可以轻松访问。我的代码看起来像这样:
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层深的嵌套,并且需要很长时间才能构建大型结果集。我意识到构建映射的时间/访问数据的时间之间存在权衡,但我想知道是否有一种更有效的方法来存储数据,以便在代码中轻松访问,或者有一种方法可以使我当前的脚本更高效-这种哈希构建循环是我目前的瓶颈。谢谢。
发布于 2011-03-21 16:28:09
Ruby的惯用做法是使用Hash构造器来弥补缺少的键:
>> 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#inject的Enumerable#group_by或某种SQL级别的分组来构建嵌套哈希。只是一些原始的想法,这样你就可以玩一玩。
发布于 2011-03-21 16:28:40
如果将数组指定为键呢?例如
my_hash[[ip, date, port]] = resp甚至是
my_hash[[ip, date, port, resp]] = true这取决于你的目的。这将减少不必要的嵌套,并提高效率。
https://stackoverflow.com/questions/5375149
复制相似问题