使用负整数进行Ruby数组排序时的行为不一致

时间:2012-04-06 21:51:56

标签: ruby arrays sorting

给出类似

的数组
x = [1, 3, 5, -1, -3, -5]

如果我们使用命令

x.sort {|i| i}

我们得到了

x = [-1, -3, -5, 1, 3, 5]

根据我们的数组,是否有任何方法让它以正负的升序/降序返回? E.g。

x = [-5, -3, -1, 1, 3, 5] or [5, 3, 1, -1, -3, -5]

编辑:

似乎x.sort可以解决这个问题,但是如果有一个更复杂的问题,我想根据哈希中给出的值从我的数组中排序,例如

x = [{:i=>1}, {:i=>2}, {:i=>3}, {:i=>4}, {:i=>5}]
y = {3=>10, 4=>-1, 2=>-2, 5=>-3, 1=>-4}

我希望能够根据y中的值对x进行排序,以便我的结果是

x = [{:i=>3}, {:i=>4}, {:i=>2}, {:i=>5}, {:i=>1}]

3 个答案:

答案 0 :(得分:7)

x = [1, 3, 5, -1, -3, -5]
x.sort # => [-5, -3, -1, 1, 3, 5]
x.sort {|a,b| a <=> b} # => [-5, -3, -1, 1, 3, 5]
x.sort {|a,b| b <=> a} # => [5, 3, 1, -1, -3, -5]

由于Array#sort method预期的返回值,您的示例会产生意外结果。基本上,当你只返回第一个参数时(当预期有两个时),解释器只查看元素的符号( - / 0 / +)并使用它来进行排序。因此,根据底层排序算法,当它产生从数组到块的对时,它只查看第一个元素的符号,如下所示:

compare(1, 3) # => 1 (wrong, should be -1 since 1 < 3)
compare(1, 5) # => 1 (wrong, should be -1 since 1 < 5)
compare(1, -1) # => 1 (right, by complete accident)

[编辑] 根据您更新的问题,请尝试使用以下排序比较器块:

x.sort! {|a,b| y[b[:i]] <=> y[a[:i]]}
x # => [{:i=>3}, {:i=>4}, {:i=>2}, {:i=>5}, {:i=>1}]

哪些读取 - 通过在哈希{{1}中查找其x属性,比较每个元素对ab,对数组:i进行排序。并按降序比较这些值。

答案 1 :(得分:2)

到目前为止,没有人提到Enumerable#sort_by,我感到很惊讶。虽然对于您的原始问题sort显然是正确的答案,但sort_by可能会按预期使用该块。您的更新问题也很容易解决:

x = [-1, -3, -5, 1, 3, 5]
x.sort_by { |i| i } 
#=> [-5, -3, -1, 1, 3, 5]

x = [{:i=>1}, {:i=>2}, {:i=>3}, {:i=>4}, {:i=>5}]
y = {3=>10, 4=>-1, 2=>-2, 5=>-3, 1=>-4}
x.sort_by { |x| -y[x[:i]] } 
#=> [{:i=>3}, {:i=>4}, {:i=>2}, {:i=>5}, {:i=>1}]

答案 2 :(得分:0)

x.sort # => [-5, -3, -1, 1, 3, 5]