1

给定一个数组

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

如果我们使用命令

x.sort {|i| i}

我们被给予

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

有没有什么办法,给定我们的数组,让它以正确的升序/降序和负数返回它?例如

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}]
4

3 回答 3

8
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方法预期的返回值,您的示例产生了意外的结果。基本上,当您只返回第一个参数时(当需要两个参数时),解释器只查看元素的符号 (-/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}]

其中读取 -x通过比较每个元素对对数组进行适当的排序,ab通过在哈希中查找它们的:i属性y并按降序比较这些值。

于 2012-04-06T21:56:12.630 回答
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}]
于 2012-04-06T22:56:09.980 回答
0
x.sort # => [-5, -3, -1, 1, 3, 5] 
于 2012-04-06T21:54:35.060 回答