排序在一个新的领域

问题描述:

所以我也有我命令调用排序上排序在一个新的领域

all.sort {|a,b| b.time<=> a.time} 

现在最近我添加了一个新的领域,以我的对象包括“UPLOADED_AT”时间事件的数组。我想首先按“时间”和“上传时间”排序(因为“时间”字段很简单,没有任何时间的日期)

我需要记住所有旧的“事件” (我不关心具有相同时间的两个事件的顺序并且没有上传的值

尝试一些东西,但是这个方法不可能存在,所以这个方法不可能存在。是这样的:

all.sort_by { |x| [x.time, (x.uploaded_at rescue Time.utc(1970))] } 
+0

当我这样做时,它会产生一个NoMethodError! – Steve 2012-01-08 19:30:37

+0

好吧我编辑它,所以看到我的新答案 – 2012-01-08 19:32:00

+0

我不认为你可以比较阵列与'nil's,它应该设置一个默认的基准时间,例如:'[x.time,x.respond_to?( :uploaded_at)? x.uploaded_at:Time.utc(1970)]' – tokland 2012-01-08 19:36:19

你将会有一定的照顾来处理uploaded_atnil值的问题是x <=> nilnil <=> x将为nil,除非x.nil?和排序要求<=>运算符返回Fixnum。

一种选择是nil点地图到一些非nil值,将永远正确排序,Time.new(0)也许是:

all.sort_by { |a| [a.time, a.uploaded_at || Time.new(0)] } 

Array#<=>运营商组成,通过成分和上述去除nil问题。如果你想在另一端nil s那么选择一些大而不是Time.new(0)

另一个选项是处理手动nil S:

all.sort do |a, b| 
    x = a.time <=> b.time 
    if(x != 0) 
     x 
    elsif(a.uploaded_at.nil? && b.uploaded_at.nil?) 
     0 
    elsif(a.uploaded_at.nil?) 
     1 
    elsif(b.uploaded_at.nil?) 
     -1 
    else 
     a.uploaded_at <=> b.uploaded_at 
    end 
end 

你会的,当然,调整elsif(a.uploaded_at.nil?)elsif(b.uploaded_at.nil?)树枝把你想让他们的nil秒。