2017-08-02 16 views
0

私は、レールアプリケーションのグループ化された選択で使用するソートされたハッシュを構築しています。私はActiveRecordを使用していません。これより効率的な方法や清潔な方法がありますか?Rubyオブジェクトのコレクションからソートされたハッシュを構築する効率的な方法はありますか?

def for_select 
    select_list = {} 
    Department.all.each do |dept| 
    select_list[dept.top_level_department_cn] ||= [] 
    select_list[dept.top_level_department_cn] << [dept.cn, dept.sorid] 
    end 
    select_list.each_value { |select_options| select_options.sort_by!(&:first) } 
      .sort 
      .to_h 
end 
+1

それはActiveRecordのない場合 'Department.all'何ですか? –

+1

これはLDAPエントリのカスタムオブジェクトです。 – HarlemSquirrel

答えて

1
def for_select 
    Department.all 
    .sort 
    .group_by(&:top_level_department_cn) 
    .each_value{|v| v.map!{|dept| [dept.cn, dept.sorid]}.sort_by!(&:first)} 
end 
+0

'Department'はActiveRecordモデルではないため、ソート自体は機能しません。ここで非常に役立つ '#group_by'列挙子を忘れてしまいました! – HarlemSquirrel

+0

また、 'sort_by(&:cn)'で部門の初期セットをソートすると、2番目の '#sort_by! 'が不要になります。 – HarlemSquirrel

+1

'Department'に' <=> 'を定義すると' .sort'が動作します。 :) –

1

別の解決策:

def for_select 
    # @see: https://stackoverflow.com/questions/2698460#answer-28916684 
    select_list = Hash.new { |h, k| h[k] = [] } 

    Department.all 
    .map { |d| [d.top_level_department_cn, [d.cn, d.sorid]] } 
    .sort 
    .each { |top_level_cn, data| select_list[top_level_cn] << data } 

    select_list 
end 
+0

デフォルト値でハッシュを作成できるかどうかわかりませんでした。それはとても涼しいです!しかし、リンクされたSOの答えでは、著者は 'Hash.new([]。freeze)'を推奨しています。 – HarlemSquirrel

+0

そうですが、この場合、毎回新しい配列をインスタンス化する必要があります: '.each {| top_level_cn、data |私の視点ではそれほど直感的ではありません(このように読む必要があります: '.each {| top_level_cn、data | select_list [top_level_cn] = select_list [top_level_cn] + [select_list [top_level_cn] + = [data]}'データ]} ') – romainsalles

関連する問題