ruby db结果集在哈希中的哈希中的数组

时间:2012-08-16 14:43:00

标签: ruby database hash

我有一个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 

哪个有效,但是想知道是否有更简洁的方式。

2 个答案:

答案 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"]
  }
}

在每个子哈希中保持相同的键,并使值都是数组。处理整体哈希的代码将更直接,更容易理解。