我在其中一个项目的测试失败中找到了这个例子。为什么这样做:
[[1,2,3], [2,3,4], [1,1,nil]].sort
#=> [[1, 1, nil], [1, 2, 3], [2, 3, 4]]
但这不是:
[[1,2,3], [nil,3,4], [1,1,nil]].sort
#=> ERROR: ArgumentError: comparison of Array with Array failed
经过测试的Ruby版本:2.0.0
,1.9.3
。
答案 0 :(得分:12)
它失败了,因为它超越了nil
。第一个测试示例未失败的原因是1, 1
与1, 2
的比较。它没有像nil
那样进行验证,因为它不需要。
以下示例失败,因为它最初必须超过nil
。在irb中尝试:
[1, nil, 2].sort
ArgumentError: comparison of Fixnum with nil failed
# in this example 1,2 comes before 2,1 so no need to continue in sort
# and nil is never reached
[ [2,1,3,5], [1,2,nil,6] ].sort
=> [[1, 2, nil, 6], [2, 1, 3, 5]]
答案 1 :(得分:3)
这是因为数组之间的比较是为了对它们进行排序,它是元素的元素:
在第一种情况[[1,2,3], [2,3,4], [1,1,nil]].sort
中,算法比较:
1 (of the first array) < 2 (of the second array)
1 (of the first array) = 1 (of the third array)
然后,由于有两个元素相等,我们必须比较第二个元素:
2 (of the first array) > 1 (of the third array)
然后比较结束,无需比较第3个元素。
现在,在第二种情况[[1,2,3], [nil,3,4], [1,1,nil]].sort
中,数组的第一个元素的比较包含一个nil,这将引发错误。
例如,这会引发错误:
[[1,2,3], [1,nil,4], [3,1,3]].sort
这不会:
[[2,2,3], [1,nil,4], [3,1,3]].sort
答案 2 :(得分:3)
这是因为#sort
方法使用QSort排序方法,在这种情况下,排序过程不会达到数组的最后一个值。在您的情况[1,1,nil]
中,它是nil
。在nil
的情况下,它会转到1,nil,4
,因为在最后一种情况下,#<=>
方法会返回nil
。为避免错误,您需要重新定义Array
的{{1}}方法,或使用复杂块:
#<=>