car*_*yam 3 ruby comparison comparison-operators
Ruby 带有方便的<=>比较运算符,并且原生原始类型支持它们。我想知道是否有一种简单的方法可以将它们组合起来以比较更复杂的对象,例如 Structs。例如,给定
class Datum < Struct.new(:code, :volume); end
datum1 = Datum.new('B',10)
datum2 = Datum.new('A',10)
datum3 = Datum.new('C',11)
data = [datum1, datum2, datum3]
Run Code Online (Sandbox Code Playgroud)
我想排序data的volume,然后如果volumes为相等的,由code。喜欢
data.sort {|a,b| (a.volume <=> b.volume) ??? (a.code <=> b.code)}
Run Code Online (Sandbox Code Playgroud)
我应该放入???什么?
我正在寻找一个解决方案:
<=>对于上面概述的这种简单情况,您可以使用sort_by:
data.sort_by {|a| [a.volume, a.code] }
#=> [
# #<struct Datum code="A", volume=10>,
# #<struct Datum code="B", volume=10>,
# #<struct Datum code="C", volume=11>
# ]
Run Code Online (Sandbox Code Playgroud)
如果您仅按单个属性排序,则它会变得更短:
data.sort_by(&:volume)
#=> [
# #<struct Datum code="B", volume=10>,
# #<struct Datum code="A", volume=10>,
# #<struct Datum code="C", volume=11>
# ]
Run Code Online (Sandbox Code Playgroud)
where&:volume使用Symbol#to_procand 是proc {|a| a.volume }(类似于 lambda)的简写。
如果您需要使其更复杂(即具有不同的左侧和右侧),您可以将其扩展为调用sort:
data.sort {|a,b| [a.volume, a.code] <=> [b.volume, b.code] }
#=> [
# #<struct Datum code="A", volume=10>,
# #<struct Datum code="B", volume=10>,
# #<struct Datum code="C", volume=11>
# ]
Run Code Online (Sandbox Code Playgroud)
整个事情都有效,因为<=>定义的运算符Array完全符合您的需要,适用于任意级别。
| 归档时间: |
|
| 查看次数: |
672 次 |
| 最近记录: |