如何在Ruby中对多种类型进行排序?

fdbelqdn  于 2022-09-21  发布在  Ruby
关注(0)|答案(5)|浏览(192)

假设您有一组跑步者:

runners = [al, betty, chris, debby]

您有一个方法time,它返回跑步者在比赛中的时间。

time方法总是返回浮点数的情况下,我知道您可以使用sort_by按三次对Runner进行排序,如下所示:

runners.sort_by do |runner|
    runner.time
end

但是,假设time有时返回一个字符串,比如"disqualified"。在这种情况下,你会如何根据时间对参赛者进行排序,被取消参赛资格的选手排在最后?如果你想让被取消参赛资格的选手先跑,或者换个位置呢?

oknrviil

oknrviil1#

这里有一个简单的方法。一个数组中只有两个排序字段,Ruby将按第一个条件排序,然后按第二个条件排序。

runners.sort_by do |runner|
    [(runner.time == 'disqualified') ? 1 : 0, runner.time]
end

在这里,1将在0之后排序,因此取消资格的时间将排在最后。

isr3a4wc

isr3a4wc2#

您可以为以下内容创建自定义类:

class RunningTime
  attr_reader :time

  def initialize time
    @time = time
  end

  def disqualified?
    @time == 'disqualified'
  end

  def <=> rhs
    case [disqualified?, rhs.disqualified?]
    when [false, true]
      -1
    when [true, true]
      0
    when [true, false]
      1
    else
      time <=> rhs.time
    end
  end
end

runners.sort_by {|runner| RunningTime.new(runner.time)}
igetnqfo

igetnqfo3#

时间会返回Object.time.to_f吗?如果是这样的话,对字符串调用to_f将返回0.0。如果没有,请尝试在块中调用runner.time.to_f。字符串类型的所有时间值都将为0.0。

jtw3ybtb

jtw3ybtb4#

你可以这样做:

[5,4,"disqualified",2,7].sort_by { |x| x.kind_of?(String) ? Float::INFINITY : x } 

# => [2, 4, 5, 7, "disqualified"]

在Ruby<1.9中没有Float::INFINITY,但您可以通过执行Inf = 1.0 / 0来获得它。

ebdffaop

ebdffaop5#

假设您是来自数据库的跑步者,使用单独的字段/方法检查不合格的跑步者允许您将排序逻辑推送到数据库层,这将比将所有记录加载到内存中并使用Ruby对它们进行排序更快。

相关问题