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

时间:2021-11-03 16:00:47

Suppose you have an array of runners:

假设你有一组跑步者:

runners = [al, betty, chris, debby]

And you have a method time that returns the runners time in the race.

你有一个方法时间返回赛跑者的时间。

In the case that the time method always returns a float, I know that you can sort the runners by there times using sort_by as follows:

如果时间方法总是返回一个浮点数,我知道您可以使用sort_by对跑步者进行排序,如下所示:

runners.sort_by do |runner|
    runner.time
end

However, suppose that time sometimes returned a string, say "disqualified". In that case, how would you sort the runners by time, with the disqualified runners last? What if you wanted the disqualified runners first or in some other position?

然而,假设时间有时返回一个字符串,说“取消资格”。在这种情况下,你如何按时间对跑步者进行排序,最后是不合格的跑步者?如果你想让那些不合格的运动员先跑还是换别的位置呢?

5 个解决方案

#1


5  

Here's a simple way. Just have two sort fields in an array, and Ruby will sort by the first criterion and then the second.

这是一个简单的方法。在数组中有两个排序字段,Ruby按第一个标准排序,然后第二个。

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

Here 1 will be sorted after 0, so disqualified times will come last.

这里的1将在0之后排序,因此不合格的时间将是最后一次。

#2


1  

You could create a custom class for this:

您可以为此创建一个自定义类:

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)}

#3


0  

Is time returning Object.time.to_f? If so, calling to_f on a String will return 0.0. If not, try calling runner.time.to_f in the block. All time values of type String will be 0.0.

是时候返回Object.time.to_f吗?如果是,在字符串上调用to_f将返回0.0。如果没有,试着打个电话。to_f块。字符串类型的所有时间值都是0。

#4


0  

You could do it analogous to this:

你可以做类似的事情

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

In Ruby < 1.9 there is no Float::INFINITY, but you can get it by doing Inf = 1.0 / 0.

在Ruby < 1.9中没有Float::INFINITY,但是你可以通过Inf = 1.0 / 0得到它。

#5


0  

Assuming that you're runners come from a database, using a separate field / method for checking for disqualified runners lets you push the sorting logic into the database layer, which will be faster than loading all of the records into memory & sorting them in ruby.

假设您是来自数据库的运行程序,使用一个单独的字段/方法检查不合格的运行程序,您可以将排序逻辑推入数据库层,这比将所有记录加载到内存中并在ruby中对它们进行排序要快得多。

#1


5  

Here's a simple way. Just have two sort fields in an array, and Ruby will sort by the first criterion and then the second.

这是一个简单的方法。在数组中有两个排序字段,Ruby按第一个标准排序,然后第二个。

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

Here 1 will be sorted after 0, so disqualified times will come last.

这里的1将在0之后排序,因此不合格的时间将是最后一次。

#2


1  

You could create a custom class for this:

您可以为此创建一个自定义类:

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)}

#3


0  

Is time returning Object.time.to_f? If so, calling to_f on a String will return 0.0. If not, try calling runner.time.to_f in the block. All time values of type String will be 0.0.

是时候返回Object.time.to_f吗?如果是,在字符串上调用to_f将返回0.0。如果没有,试着打个电话。to_f块。字符串类型的所有时间值都是0。

#4


0  

You could do it analogous to this:

你可以做类似的事情

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

In Ruby < 1.9 there is no Float::INFINITY, but you can get it by doing Inf = 1.0 / 0.

在Ruby < 1.9中没有Float::INFINITY,但是你可以通过Inf = 1.0 / 0得到它。

#5


0  

Assuming that you're runners come from a database, using a separate field / method for checking for disqualified runners lets you push the sorting logic into the database layer, which will be faster than loading all of the records into memory & sorting them in ruby.

假设您是来自数据库的运行程序,使用一个单独的字段/方法检查不合格的运行程序,您可以将排序逻辑推入数据库层,这比将所有记录加载到内存中并在ruby中对它们进行排序要快得多。