按字母顺序排序并按组显示

时间:2012-04-09 16:06:06

标签: ruby-on-rails ruby ruby-on-rails-3

我正在尝试按字母顺序和块中显​​示数据库中的标题列表。

我想输出这封信,然后包括以该字母开头的所有标题。例如:

    • 苹果
    • anotherthing
    • 鲍勃

我知道我可以使用.order('title')订购我的结果,但我不确定编写显示代码的最佳方法是什么?

2 个答案:

答案 0 :(得分:8)

titles.group_by {|word| word[0].upcase }

那么,如果:

titles = ['Apple', 'anothersomething', 'Bob']

然后:

grouped_titles = titles.group_by {|word| word[0].upcase }
 => {"A"=>["Apple", "anothersomething"], "B"=>["Bob"]} 

为了确定排序,您可以对生成的Hash进行排序,将其转换为数组:

grouped_titles = grouped_titles.sort_by{|k, v| k}
 => [["A", ["Apple", "anothersomething"]], ["B", ["Bob"]]] 

然后你可以遍历生成的数组。

<% grouped_titles.each do |initial_letter, titles| %>
 -display stuff here-
<% end %>

请注意,这是在Ruby中进行分组,而不是在数据库中进行分组(可以通过在关系上使用.group方法来完成),但是如果您已经在页面中显示了所有数据,则此方法应该没事。

答案 1 :(得分:0)

我认为@MrTheWalrus提出的解决方案是有效的,只要你在列表中正确迭代以维持秩序,但我会提出一个替代方案,如果你的列表变长,会更快一些。首先确保您的列表按顺序排列,如您所做的那样:

@titles = Title.order(:title)

然后视图中的迭代将如下所示:

<% cur_letter = nil %>
<% @titles.each do |t| %>
  <% title_letter = t.name[0].capitalize.match(/[A-Z]/) ? t.name[0].capitalize : "#" %> 
  <% if title_letter != cur_letter %>
    <% cur_letter = title_letter %>
    <%= cur_letter %>
  <% end %>
  <%= t.name %>
<% end %> 

我承认它作为视图代码有点难看,但是它允许你在列表中迭代一次,维护顺序,并避免group_by这不是一个简单的操作。