使用宇宙飞船运算符按 Ruby 中的 2 个属性对数组中的对象进行排序
Sort objects in array by 2 attributes in Ruby with the spaceship operator
我有一个 SizeMatters
class 从给定的字符串创建一个对象。为了对数组中的这些对象进行排序,我实现了 <=>(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)
以便数组中的对象可以先按大小排序,然后按字母顺序排序?
像这样定义<=>
:
def <=>(other)
[str.size, str] <=> [other.str.size, other.str]
end
你说你想按大小对字符串进行排序,并通过按字典顺序 ("dictionary") 对相同长度的字符串进行排序来打破平局。是的,您将需要定义 SizeMatters#<=>
,但将其定义为排序可能是错误的,因为这会阻止您以正常方式在 class 的其他地方比较字符串。考虑保留 <=>
的定义并使用 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
我有一个 SizeMatters
class 从给定的字符串创建一个对象。为了对数组中的这些对象进行排序,我实现了 <=>(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)
以便数组中的对象可以先按大小排序,然后按字母顺序排序?
像这样定义<=>
:
def <=>(other)
[str.size, str] <=> [other.str.size, other.str]
end
你说你想按大小对字符串进行排序,并通过按字典顺序 ("dictionary") 对相同长度的字符串进行排序来打破平局。是的,您将需要定义 SizeMatters#<=>
,但将其定义为排序可能是错误的,因为这会阻止您以正常方式在 class 的其他地方比较字符串。考虑保留 <=>
的定义并使用 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