2016-07-27 9 views
0

を依存し、私は通常、このような項目の配列(int型)の最大発生をカウント取得:ルビー:多くのハッシュの最大出現がその内容

specialties_with_frequency = specialties.inject(Hash.new(0)) { |h,v| h[v] += 1; h } 
@reference.specialty_id = specialties.max_by { |v| specialties_with_frequency[v] } 

今日、私はハッシュの最大発生をカウントする必要がありますコンテンツ。

品種は、これらのフィールドを含むデータベース・オブジェクトです: ID、grape_id、パーセント

私の重複オブジェクトは、複数の品種を持つことができます。例えば

@duplicates.each do |duplicate| 
    duplicate.varietals.each do |varietal| 
    end 
end 

、重複をbrowsings、私が持っています。この場合

duplicate 1: varietals => {grape_id => 1}, {grape_id => 2} 
duplicate 2: varietals => {grape_id => 3} 
duplicate 3: varietals => {grape_id => 1}, {grape_id => 2} 
duplicate 4: varietals => {grape_id => 3}, {grape_id => 5} 

を、受け入れたデータは次のようになります。

{grape_id => 1}, {grape_id => 2} 

すべての重複を閲覧2件の発生があるため。

私はすべての出現でどのように同じ値を探索するのか分かりません。

おかげで、 アレクサンドル

答えて

0

は、あなただけのあなたの周波数ハッシュのキーとして品種アレイと、以前のようにまったく同じコードを使用することができます。同じ内容のキーが等しくなるように配列がソートされていることを確認してください。 grape_idが出現チェックのために使用される唯一のフィールドである場合

、あなたはその場合には、あなたの周波数ビルダーは次のようになります、数字の配列に品種の配列をマッピングすることにより、ビットを簡素化することができます。

specialties_with_frequency = @duplicates.inject(Hash.new(0)) do |h, duplicate| 
    grape_ids = duplicate.varietals.map { |v| v[:grape_id] }.sort 
    h[grape_ids] += 1; h 
end 

はあなたが提供した例を考えると、値が今のようになります。配列では

{[1, 2]=>2, [3]=>1, [3, 5]=>1} 
+0

を使用するか、配列の代わりにセットを使用します。常に同じ単一キーを含むハッシュの配列の代わりに値の配列を使用してください。 –

+0

ラース、コードのおかげで。 hオブジェクトでmax_byを使用する必要はありませんか?結果はすでに最大から最小の出現順に並べられていますか? –

+0

@ alex.bour:ハッシュは順序付けされていないので、前と同じように最大値を抽出する必要があります。 –

0

、それが使用することをお勧めしますハッシュEnumerable#group_by

with_freq = whatever.group_by { |v| v } # (&:itself) for ruby2.3 
        .map { |k, v| [k, v.count] } 
        .to_h 

グループ化のための高度なアルゴリズムが必要な場合は、{ |v| v }を変更してこのアルゴリズムを使用してください。