0

我有一个SizeMatters从给定字符串创建对象的类。为了对数组中的这些对象进行排序,我实现了该<=>(other)方法。但以下代码仅有助于按大小对对象进行排序。我还希望数组按字母顺序排序。

class SizeMatters
  include Comparable
  attr :str
  def <=>(other)
    str.size <=> other.str.size
  end
  def initialize(str)
    @str = str
  end
  def inspect
    @str
  end
end

s1 = SizeMatters.new("Z")
s2 = SizeMatters.new("YY")
s3 = SizeMatters.new("xXX")
s4 = SizeMatters.new("aaa")
s5 = SizeMatters.new("bbb")
s6 = SizeMatters.new("WWWW")
s7 = SizeMatters.new("VVVVV")

[ s3, s2, s5, s4, s1 , s6, s7].sort #[Z, YY, bbb, xXX, aaa, WWWW, VVVVV]

我想要的是这个

[ s3, s2, s5, s4, s1 , s6, s7].sort #[Z, YY, aaa, bbb, xXX, WWWW, VVVVV]

如何编写<=>(other)以便数组中的对象可以先按大小排序,然后按字母顺序排序?

4

2 回答 2

5

像这样定义<=>

   def <=>(other)
     [str.size, str] <=> [other.str.size, other.str]
   end
于 2017-07-02T11:55:31.563 回答
1

您说您想按大小对字符串进行排序,并通过按字典(“字典”)顺序对相同长度的字符串进行排序来打破平局。是的,您需要定义SizeMatters#<=>,但定义它以进行排序可能是错误的,因为这会阻止您以正常方式在班级其他地方比较刺痛。考虑保留您的定义<=>并使用Enumerable#sort_by进行排序。

class SizeMatters
  include Comparable

  attr_reader :str

  def initialize(str)
    @str = str
  end

  def <=>(other)
    str.size <=> other.str.size
  end

  def sort_criteria
    [str.size, str]
  end

  def lexi_precede?(other)
    str < other.str
  end
end

[s3, s2, s5, s4, s1 , s6, s7].sort_by(&:sort_criteria).map(&:str)
  #=> ["Z", "YY", "aaa", "bbb", "xXX", "WWWW", "VVVVV"]

s1.lexi_precede?(s2)
  #=> false
于 2017-07-02T18:39:23.510 回答