【发布时间】:2019-08-10 22:43:20
【问题描述】:
我正在实现自定义排序。有宇宙飞船运算符<=> 处理数组排序:
myArray.sort { |a, b| a <=> b }
-
当
b大于a时,a <=> b返回1,并且交换了两个元素。 -
当
a等于b时,a <=> b返回0,并且两个元素保持在原来的位置。 -
当
a小于b时,a <=> b返回-1,并且两个元素保持在原来的位置。
所以我用一个例子进行了测试:
myArray = [2, 1, 7, 9, 3, 8, 0]
myArray.sort { |a, b| 1 <=> 1 } # making it always return 0
#=> [9, 1, 7, 2, 3, 8, 0]
结果不是我所期望的。在我的预期中,当宇宙飞船运算符返回0 时,每个元素都将保持在原始位置。由于在上面的示例中,spaceship 运算符始终返回 0,因此数组应保持原样。但是,结果与原始数组不同。
我有什么误解吗?
更新:
以下是我上述问题的来源。
最初我试图通过属性对对象进行排序(假设属性是status)。
例如
myObjects = [obj1, obj2,..., objn] # the objects are ordered by create_time already
myObjects.sort{|a,b|
case a.status
when 'failed'
x = 1
when 'success'
x = 0
when 'pending'
x = -1
end
case b.status
when 'failed'
y = 1
when 'success'
y = 0
when 'pending'
y = -1
end
x <=> y # compare two objects (a and b) by the status
}
myObjects 已经按created_time 排序,但我想按每个对象的status 再次排序。
例如,
两个具有相同created time的对象(这里只考虑小时和分钟,忽略秒)将再次按它们的状态排序,使具有failed状态的对象放在数组的末尾。
上面代码中的x 和y 值将取决于对象的状态,
和x y 比较来决定顺序。如果两个对象的状态相等(x == y),则元素应该保持在相同的位置,因为它们已经按created_time排序,不需要再次排序。
当两个对象的状态都是success时,x <=> y会返回0。
但是根据一些cmets的说法,spaceship算子返回的比较值0似乎输出了不可预测的顺序。
如果myObjects 包含所有具有相同状态的元素怎么办?这将导致宇宙飞船运算符自 x == y 以来一直返回 0。
在我的预期中,myObjects 应该保持相同的顺序,因为状态都是一样的,在我的情况下使用 spaceship 运算符时应该如何更正?
非常感谢大家的帮助!
【问题讨论】:
-
不是空间操作员,是宇宙飞船操作员。空间看起来不像
<=>。 -
"[W]当空间运算符返回0时,每个元素都将保持在原来的位置"--这是从何而来的?
-
你可以用
0而不是1 <=> 1,所以这不是因为宇宙飞船运算符。 -
@sawa 因为我认为当宇宙飞船运算符返回 1 时,Ruby 会交换元素。这就是为什么我认为 Ruby 在看到 0 或 -1 时会不理会元素。我的概念正确吗?