0

ハッシュの配列であるデータのセットがあり、各ハッシュは 1 つのデータ レコードを表します。

data = [
  {
    :id => "12345",
    :bucket_1_rank => "2",
    :bucket_1_count => "12",
    :bucket_2_rank => "7",
    :bucket_2_count => "25"
  },
  {
    :id => "45678",
    :bucket_1_rank => "2",
    :bucket_1_count => "15",
    :bucket_2_rank => "9",
    :bucket_2_count => "68"
  },
  {
    :id => "78901",
    :bucket_1_rank => "5",
    :bucket_1_count => "36"
  }
]

ランク値は常に 1 から 10 の間です。

私がやろうとしているのは、最終的な結果セットのキーとしてランク フィールド (:bucket_1_rankおよびフィールド) の可能な値のそれぞれを選択することです。各キーの値は、関連するフィールドのすべての値の配列になります。したがって、上記のデータについて、私が念頭に置いている最終的な結果の構造は次のようなものです。:bucket_2_rank:bucket_count

バケット 1:

 {"2" => ["12", "15"], "5" => ["36"]}

バケット 2:

{"7" => ["25"], "9" => ["68"]}

フィールド名が同じままであるという前提の下で、またはフィールド/キー名をハードコーディングするか、group_by必要なフィールドを使用するだけで、これを行うことができますが、私の問題は、毎月異なるデータセットを使用して作業することです。ランク フィールドの名前は、プロジェクトの仕様によって若干異なります。フィールド名をハード コーディングするのではなく、カウント フィールドとランク フィールドの名前を動的に識別したいと考えています。

私は 2 つのクイック ヘルパーget_ranksget_buckets作成し、正規表現を使用してランク フィールドまたはカウント フィールドのいずれかであるフィールド名の配列を返します。これは、これらのフィールドの名前に常にリテラル文字列「_rank」または「_count」が含まれるためです。

ranks = get_ranks
counts = get_counts

results = Hash.new{|h,k| h[k] = []}

data.each do |i|
  ranks.each do |r|
    unless i[r].nil?
      counts.each do |c|
          results[i[r]] << i[c]
      end
    end
  end
end

p results

これは近いように見えますが、ぎこちなく感じます。このデータセットを反復処理するためのより良い方法が必要だと私には思えます。Ruby を使用してこのプロジェクトに取り組んだことがないので、ハッシュの配列を反復処理したり、配列を値としてハッシュに入力したりすることについての理解を深める機会としてこれを使用します。リソース/提案は大歓迎です。

4

1 に答える 1

1

次のように短縮できます。

result = Hash.new{|h,k| h[k] = Hash.new{|h2,k2| h2[k2] = []}}
data.each do |hsh|
    hsh.each do |key, value|
        result[$1][value] << hsh["#{$1}_count".to_sym] if key =~ /(.*)_rank$/
    end
end

puts result
#=> {"bucket_1"=>{"2"=>["12", "15"], "5"=>["36"]}, "bucket_2"=>{"7"=>["25"], "9"=>["68"]}}

これは、:bucket_2_item_count実際には であると想定していますが:bucket_2_count

于 2012-09-18T19:49:55.517 に答える