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

Ruby:对可能包含nil的多维数组进行排序有时会失败,ruby,arrays,sorting,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.0,1.9.3这是因为数组之

我在一个项目的失败测试中发现了这个例子。为什么这样做有效:

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

这是因为数组之间进行了比较,以便对它们进行排序,这是元素对元素:

在第一种情况下,算法比较:

1 (of the first array) < 2 (of the second array)
1 (of the first array) = 1 (of the third array)
然后比较完成,无需比较第三个元素

现在,在第二种情况下,
[[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

它失败是因为它超过了
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]]
这是因为
#sort
方法使用排序方法,在某些情况下,排序过程不会达到数组的最后一个值。在您的情况下,
[1,1,nil]
nil
。在
1,nil,4的情况下,它达到
nil
,因为在最后一种情况下
#
方法返回
nil
。为了避免错误,您需要重新定义数组的方法,或者使用复杂块:

[[1,2,3], [nil,3,4], [1,1,nil]].sort do| x, y |
   x <=> y || 1
end
[[1,2,3],[nil,3,4],[1,1,nil]]排序do | x,y|
x y | | 1
结束

@majioa避免在评论中回答。好吧,这里有一种解决方法:
[1,2,nil]。排序{x,y | x.to_iy.to_i}
,因为有人可能在寻找它。更简短的是:
[1,2,nil]。排序依据&:to_i
[[1,2,3], [nil,3,4], [1,1,nil]].sort do| x, y |
   x <=> y || 1
end