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