2

次のような結果を返す 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 

どちらが機能しますが、もっときちんとした方法があるかどうか疑問に思っていました。

4

2 に答える 2

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

各サブハッシュに同じキーを保持し、値をすべて配列にします。その全体的なハッシュを処理するためのコードは、より単純で従うのが簡単になります。

于 2012-08-16T15:09:39.917 に答える
1

私はマイケルに同意します。あなたの方法には何の問題もありません。コードの背後にある意図は簡単にわかります。

派手になりたい場合は、(多くの)方法の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

これにより、メソッドと同じ時間の複雑さが得られるはずです。

于 2012-08-16T15:02:01.150 に答える