【发布时间】:2012-04-09 16:06:06
【问题描述】:
我正在尝试按字母顺序和块显示我的数据库中的标题列表。
我想输出该字母,然后包含以该字母开头的所有标题。例如:
- 一个
- 苹果
- 另一件事
- 乙
- 鲍勃
我知道我可以使用 .order('title') 对结果进行排序,但我不确定编写显示代码的最佳方式是什么?
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3
我正在尝试按字母顺序和块显示我的数据库中的标题列表。
我想输出该字母,然后包含以该字母开头的所有标题。例如:
我知道我可以使用 .order('title') 对结果进行排序,但我不确定编写显示代码的最佳方式是什么?
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3
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 方法来完成),但是如果您已经在页面中显示了所有数据,则该方法应该是很好。
【讨论】:
("A".."Z") 和 (0..9) 这样的范围。
我认为@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 这不是一个简单的操作。
【讨论】: