Ruby:对包含nil的多维数组进行排序有时会失败

时间:2014-01-24 15:38:00

标签: ruby arrays sorting

我在其中一个项目的测试失败中找到了这个例子。为什么这样做:

[[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.01.9.3

3 个答案:

答案 0 :(得分:12)

它失败了,因为它超越了nil。第一个测试示例未失败的原因是1, 11, 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}}方法,或使用复杂块:

#<=>