3

我有一个现有的 activerecord 数组,通过以下方式获得:

@posts = Post.where(["created_at > ?", n_days.days.ago])

我想根据需要从多列实时计算的值来订购这个数组:

posts_array = posts.map { |p| [p.id, f(t, p.x,p.y)] }

这给出了一个类似 的数组[[1,20],[2,11],[3,14], ...],然后我根据要给出的函数值对其进行排序[[1,20],[3,14],[2,11],...],然后最终得到order_array我想要的[1,3,2,...]

@posts然后基于新的重新排序原始数组的最佳方法是什么order_array [1,3,2,...]?如果可能,我不想再次接触数据库,因为信息已经包含在@posts数组中。

有没有一种简单的方法可以做到这一点?

4

2 回答 2

4

如果你不需要posts_array数组,你可以做

@posts = Post.where(["created_at > ?", n_days.days.ago])
@posts.sort_by! { |p| f(t, p.x, p.y) }
于 2013-05-09T13:52:11.140 回答
1

获取 order_array

显而易见的答案是:

[[1,20],[2,11],[3,14]].sort{|a,b| b[1] <=> a[1]}.map{|x| x[0]}
 => [1, 3, 2] 

不确定是否有人能想出更聪明的方法?

在 ruby​​ 2.0 上,您可以使用lazy避免在排序后扩展数组(并获得一些性能)

[[1,20],[2,11],[3,14]].lazy.sort{|a,b| b[1] <=> a[1]}.map{|x| x[0]}

按顺序检索帖子

最简单的解决方案是

Post.find(order_array).sort{|a,b| order_array.index(a.id) <=> order_array.index(b.id)}

但简单点会更好

order_array.map{|x| Post.find(x)}

或者使用您已经加载的@post列表:

 order_array.map{|x| @post.find{|y| y.id == x)}
于 2013-05-09T13:44:12.547 回答