我正在混合2个数组,并希望按照created_at属性对它们进行排序:
@current_user_statuses = current_user.statuses
@friends_statuses = current_user.friends.collect { |f| f.statuses }
@statuses = @current_user_statuses + @friends_statuses
@statuses.flatten!.sort!{ |a,b| b.created_at <=> a.created_at }
@current_user_statuses
和@friends_statuses
各自排序正确,但合并后排序不正确,@friends_statuses
始终显示在顶部,按其created_at
属性和{{排序底部的1}}按其@current_user_statuses
属性排序。
这是观点:
created_at
答案 0 :(得分:3)
尝试:
(current_user.statuses + current_user.friends.collect(&:statuses)) \
.flatten.compact.sort_by(&:created_at)
答案 1 :(得分:1)
你不能像这样以flatten!
方式菊花链。如果未对数组进行任何更改,则flatten!
将返回nil。当你排序零时,什么都不会发生。
您需要将它们分开:
@statuses.flatten!
@statuses.sort! { ... }
答案 2 :(得分:0)
我是这样做的:
设置课程:
class User
class Status
attr_reader :statuses, :created_at
def initialize(stats)
@statuses = stats
@created_at = Time.now
end
end
attr_reader :statuses, :friends
def initialize(stats=[], friends=[])
@statuses = Status.new(stats)
@friends = friends
end
end
定义一些实例,只是为了好玩而有一些时间差距:
friend2 = User.new(%w[yellow 2])
sleep 1
friend1 = User.new(%w[orange 1])
sleep 2
current_user = User.new(%w[green 1], [friend1, friend2])
这是我如何以不同的方式做到这一点;以created_at
顺序获取状态:
statuses = [
current_user.statuses,
current_user.friends.collect(&:statuses)
].flatten.sort_by(&:created_at)
看起来像:
require 'pp'
pp statuses
# >> [#<User::Status:0x0000010086bd60
# >> @created_at=2011-07-02 10:49:49 -0700,
# >> @statuses=["yellow", "2"]>,
# >> #<User::Status:0x0000010086bc48
# >> @created_at=2011-07-02 10:49:50 -0700,
# >> @statuses=["orange", "1"]>,
# >> #<User::Status:0x0000010086bb30
# >> @created_at=2011-07-02 10:49:52 -0700,
# >> @statuses=["green", "1"]>]
我只是构建一个临时的包含数组来保存current_user的状态,加上所有朋友的状态,然后展平它。
(&:statuses)
和(&:created_at)
参数对于实例的statuses
方法或实例的created_at
方法而言是Rails的简写。
答案 3 :(得分:0)
@statuses = (@current_user_statuses + @friends_statuses).sort_by(&:created_at)
答案 4 :(得分:0)
我知道您的问题已经发布了几个解决方案。但是当状态数量增加时,所有这些解决方案都可能会破坏您的系统。对于此数据集,您必须在数据库层中执行排序和分页,而不是在Ruby层中执行
方法1:简洁明了
Status.find_all_by_user_id([id, friend_ids].compact, :order => :created_at)
方法2:长而有效
class User
def all_statuses
@all_statuses ||=Status.all( :joins => "JOIN (
SELECT friend_id AS user_id
FROM friendships
WHERE user_id = #{self.id}
) AS friends ON statuses.user_id = friends.user_id OR
statuses.user_id = {self.id}",
:order => :created_at
)
end
end
现在,您可以在单个查询中获取已排序的状态:
user.all_statuses
PPS:如果这是我的代码,我会进一步优化SQL。有关更多详细信息,请参阅此answer。