2017-08-02 46 views
0

我正在构建一个分类的散列,用于在Rails应用程序中的分组选择。我没有使用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

什么'Department.all'如果不是ActiveRecord的? –

+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)'排序最初的部门集合使得第二个'#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 | select_list [top_level_cn] + = [data]}',这在我看来不太直观(你必须像这样读取:'.each {| top_level_cn,data | select_list [top_level_cn] = select_list [top_level_cn] + [数据]}') – romainsalles

相关问题