如何使用sort_by方法从Win / Loss数据中对团队进行排序

时间:2014-03-03 07:00:57

标签: ruby sorting hash-of-hashes

我对如何使用sort_by方法感到困惑。我该如何重新排列:

@final_leaderboard = {
                     "Patriots" => {"Win"=>3, "Loss"=>0},
                     "Broncos" => {"Win"=>1, "Loss"=>1},
                     "Colts" => {"Win"=>0, "Loss"=>2},
                     "Steelers" => {"Win"=>0, "Loss"=>1},
                     }

产生这个:

Patriots  3   0
Broncos   1   1
Steelers  0   1
Colts     0   2

到目前为止,我有这个代码,但是它已经反转了,并且Loss值不正确。我想要做的是先按获胜条件排序。获胜最多的球队将在@final_leaderboard哈希中的第一项,由野马队赢得1胜,然后是钢人队和小马队。但是,我也希望按损失排序。例如,我希望Steelers被列为@final_leaderboard哈希中的第三项,因为它有一个损失,而不是有两个的马驹。

@final_leaderboard = @final_leaderboard.sort_by do |key,value|
  value["Loss"] <=> value["Win"]
end

上面的代码片段会产生以下输出:

Patriots 3  0
Broncos  1  1
Colts    0  2
Steelers 0  1

最后两项是不正确的,但我不知道需要在代码片段中更改哪些需要更改Steelers和Colts。我不熟悉sort_by方法和Ruby Docs上的sort_by方法示例/解释没有像其他方法那样的可视化示例,所以我不太清楚如何使用它。如果有人可以请我解释如何对最后两个项目进行排序,我会很感激。谢谢。

3 个答案:

答案 0 :(得分:4)

此代码执行您所解释的内容:

@final_leaderboard.sort_by{|_, v| [-v["Win"], v["Loss"]]}

结果

[
  ["Patriots", {"Win"  => 3, "Loss" => 0}],
  ["Broncos", {"Win"  => 1, "Loss" => 1}],
  ["Steelers", {"Win"  => 0, "Loss" => 1}],
  ["Colts", {"Win"  => 0, "Loss" => 2}]
]

如果要按多个条件排序,则在sort_by块中使用数组。这里给出的[-v["Win"], v["Loss"]]指示首先通过比较每个哈希的-v["Win"](其中v是哈希值)进行排序,这是按Win的降序排序,然后如果存在平局,则会查看v["Loss"],即按Loss的升序排序。

答案 1 :(得分:0)

无论两个操作数之间的差异如何,

<=>仅返回1,0或-1:

1 <=> 7    # => -1
1 <=> 5    # => -1
3 <=> 2    # => 1
3 <=> 0    # => 1

您最好使用-运算符。

除此之外,sortsort_by首先产生的价值很小。要首先列出较高分(win - loss),您需要否定分数。

除此之外,要获得所需的完全相同的输出,您需要使用String%#sprintf格式化输出:

board.sort_by { |key,value| value['Loss'] - value['Win'] }.each do |key, value|
  puts "%-10s %2s %3s" % [key, value['Win'], value['Loss']]
end

输出:

Patriots    3   0
Broncos     1   1
Steelers    0   1
Colts       0   2

<强>更新

这个答案是基于对排名的错误假设。请参阅sawa's answer

答案 2 :(得分:0)

如果您的意思是先按Win号码排序,然后按Loss号码排序( 订单按Win desc,损失asc ),那么您可能如下所示:

@final_leaderboard = @final_leaderboard.sort do |a, b|
  a[1]['Win'] == b[1]['Win'] ? a[1]['Loss'] <=> b[1]['Loss'] :  b[1]['Win'] <=> a[1]['Win']
end