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

4
我正试图按字母顺序和块格式从我的数据库中显示标题列表。我想要输出字母,然后包括以该字母开头的所有标题。例如:
  • A
    • Apple
    • anotherthing
  • B
    • Bob
我知道可以使用.order('title') 来排序结果,但我不确定如何编写最佳的显示代码?
2个回答

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方法可以在数据库中完成),但是如果您已经在页面上显示了所有数据,则此方法应该可以正常工作。

谢谢。我还有数字,所以我添加了group_by{|word| word.name[0].capitalize.match(/[A-Z]/) ? word.name[0].capitalize : "#" } - spyderman4g63
你会失去顺序,因为它是一个哈希表。我建议使用范围操作符,如 ("A".."Z")(0..9) 进行迭代。 - tsherif
实际上,从1.9版本开始,Ruby的Hash是有序的(http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/),因此如果按字母顺序插入项,则在迭代时它们将保持原样。这也意味着您可以对Hash进行排序,这可能值得一试。 - MrTheWalrus
话虽如此,我已经编辑了答案,包括对哈希进行排序,这将其转换为数组 - 相同的迭代仍然有效。 - MrTheWalrus
@MrTheWalrus,有人怎么在Liquid中实现这个功能呢?这是我的问题 - Miloš Miljković

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操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接