我有一个现有的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
数组中。
有直接的方法吗?
答案 0 :(得分:4)
如果您不需要posts_array
数组,则可以
@posts = Post.where(["created_at > ?", n_days.days.ago])
@posts.sort_by! { |p| f(t, p.x, p.y) }
答案 1 :(得分:1)
显而易见的答案是:
[[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)}