Rails,Ruby,如何对数组进行排序?

68

在我的Rails应用程序中,我创建了一个数组,代码如下:

@messages.each do |message|

  @list << {
    :id => message.id,
    :title => message.title,
    :time_ago => message.replies.first.created_at
  }
end

我创建了这个数组后,想按照 time_ago 的升序对其进行排序,是否可能?

6个回答

154
 @list.sort_by{|e| e[:time_ago]}

默认情况下,它是升序排列,但如果您想要降序排列,可以执行以下操作:

 @list.sort_by{|e| -e[:time_ago]}

另外,看起来你正在试图从@messages中构建列表。你可以简单地执行以下操作:

@list = @messages.map{|m| 
  {:id => m.id, :title => m.title, :time_ago => m.replies.first.created_at }
}

1
在构建@list之后执行此操作。因此,`@messages.each do |message| @list << { :id => message.id, :title => message.title, :time_ago => message.replies.first.created_at } end`@list.sort_by... - Mike Lewis
4
针对DESC,尝试过却得到“undefined method `-@' for Wed Apr 20 20:40:35 UTC 2011:Time”错误提示。 - AnApprentice
4
如果您仍然希望以编程方式(而不是通过SQL)进行操作的话,最糟糕的情况是,您可以使用 @list.sort_by{|e| e[:time_ago]}.reverse,但这真的很奇怪,因为它对您不起作用。 - Mike Lewis
@ColdTree,你之所以得到“undefined method”错误是因为你试图否定一个时间值,比如-Wednesday,这是没有意义的。Mike Lewis假设:time_ago是一个数字值。你需要减去Time.now - message.replies.first.created_at来获得一个数字的:time_ago,然后反向排序就会起作用了。 - Chloe
我在我的Presenter和Controller中使用sort或sort_by时遇到了问题。它显示未定义方法'sort_by'。有人能解释一下吗? - Alex Jose
显示剩余5条评论

15

在Rails 4+中

@list.sort_by(&:time_ago)

12

你可以这样做:

@list.sort {|a, b| a[:time_ago] <=> b[:time_ago]}

2
更好的方法是 @list.sort_by { |m| m[:time_ago] } - Sophie Alpert

6
您可以使用 @list.sort_by { |message| message.time_ago } 进行排序。

谢谢,但是你如何定义排序顺序? - AnApprentice
你可以使用 { |message| message.time_ago } 部分来定义排序顺序。它被称为 sort_by,因为它按照块中的条件进行排序。在这里,我们要按元素的 .time_ago 成员进行排序。它总是升序排序。要进行降序排序,我们可以按该值的负数进行升序排序,如 Mike Lewis 的答案所述。 :) 如果不起作用,那是因为 time_ago 的类型没有定义否定。 :/ - Karl Knechtel

4

仅供参考,我认为将消息移动到新列表然后进行排序没有意义。在我的看法中,只要是ActiveRecord,应该直接在查询数据库时完成。

看起来您应该可以这样做:

@messages = Message.includes(:replies).order("replies.created_at ASC")

除非我误解了目的,否则这应该足够了。


0

1
Rails 4 打破了这个链接。旧的文档可以在这里找到:http://api.rubyonrails.org/v3.2.19/classes/Enumerable.html#method-i-group_by - DonPaulie
这是关于排序而不是分组的内容。 - mmsilviu

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