我有一个db查询,它返回如下结果:
db_result.each {|row| puts row}
{"IP"=>"1.2.3.4","Field1"=>"abc","Field2"=>"123"}
{"IP"=>"1.2.3.4","Field1"=>"abc","Field2"=>"234"}
{"IP"=>"1.2.3.4","Field1"=>"bcd","Field2"=>"345"}
{"IP"=>"3.4.5.6","Field1"=>"bcd","Field2"=>"456"}
{"IP"=>"3.4.5.6","Field1"=>"bcd","Field2"=>"567"}
并希望将其放入如下的哈希:
{
"1.2.3.4" => {
"abc" => ["123", "234"],
"bcd" => "345"
},
"3.4.5.6" => {
"bcd" => ["456", "567"]
}
}
我目前正在做的是:
result_hash = Hash.new { |h, k| h[k] = {} }
db_result.each do |row|
result_hash[row["IP"]] = Hash.new { |h, k| h[k] = [] } unless result_hash.has_key? row["IP"]
result_hash[row["IP"]][row["Field1"]] << row["Field2"]
end
哪个有效,但是想知道是否有更简洁的方式。
答案 0 :(得分:1)
我同意迈克尔的观点,你的方法没有任何问题。可以很容易地看到代码背后的意图。
如果你想获得幻想,这里有一种(很多)方法:
x = [
{"IP"=>"1.2.3.4","Field1"=>"abc","Field2"=>"123"},
{"IP"=>"1.2.3.4","Field1"=>"abc","Field2"=>"234"},
{"IP"=>"1.2.3.4","Field1"=>"bcd","Field2"=>"345"},
{"IP"=>"3.4.5.6","Field1"=>"bcd","Field2"=>"456"},
{"IP"=>"3.4.5.6","Field1"=>"bcd","Field2"=>"567"}
]
y = x.inject({}) do |result, row|
new_row = result[row["IP"]] ||= {}
(new_row[row["Field1"]] ||= []) << row["Field2"]
result
end
我认为这应该会产生与您的方法相同的时间复杂度。
答案 1 :(得分:1)
将此视为同行评审。作为加工和维护的建议......
我建议你想要的数据结构更加一致。
而不是:
{
"1.2.3.4" => {
"abc" => ["123", "234"],
"bcd" => "345"
},
"3.4.5.6" => {
"bcd" => ["456", "567"]
}
}
我建议:
{
"1.2.3.4" => {
"abc" => ["123", "234"],
"bcd" => ["345"]
},
"3.4.5.6" => {
"abc" => [],
"bcd" => ["456", "567"]
}
}
在每个子哈希中保持相同的键,并使值都是数组。处理整体哈希的代码将更直接,更容易理解。