我收到了@players的集合,按total_points排序。我试图找出特定的@player在@players集合中排名的位置。
示例:有5个玩家,这是他们的total_points:
鉴于我们衡量这样的关系:
仅 显示玩家4等级的最简单方法是什么?这可能没有遍历整个集合吗?我知道如何通过检查以前的迭代器的total_score是否相同来打印整个列表,但我不需要显示整个列表,只显示当前玩家的等级。
在我的应用程序中,将会有近千名玩家,所以我试图找到一种快速计算的方法。
编辑:
根据@ max的答案,我在此提出了什么:
@grouped_players = Player.all.reorder(total_points: :desc).group(:total_points).count
our_rank = 0
tied = false
@grouped_players.each do |points, count|
if points > @player.total_points
our_rank += count
end
if points == @player.total_points
our_rank += 1
if count > 1
tied = true
end
break
end
end
puts our_rank
puts tied
任何人都有更优雅的解决方案吗?
答案 0 :(得分:2)
你基本上试图找出有多少玩家得分高于当前玩家的得分,然后加1.如果total_points
是数据库属性,你应该可以打电话Player.group(:total_points).count
,在您的示例中应返回{ 20 => 2, 15 => 3 }
。然后,您选择散列中哪些元素的键大于当前玩家的分数,将值相加,然后添加1.如果您愿意,可以在数据库中执行该过程的某些部分而不是Ruby;如果你有很多不同的分数可能会更有效率(因此返回的哈希值非常大)。但是有1000名玩家,除非你频繁地进行计算,否则我认为这不是一个大问题。
答案 1 :(得分:0)
您可以使用Active Record group
方法执行此操作,如下所示。
让您拥有Player
模型,其中point
列将用于衡量排名。所以,查询就像
Player.where(point: Player.group(:point).sort[3])
您可以看到group
4th
返回数组。我们正在排序以确保4th
位置将在索引3上。现在使用第4个位置点来搜索所有用户。请注意,如果数据上没有null
位置,则会搜索具有0
值的用户。因此,请确保每个用户的点数至少为mean_by_zip = sales.groupby(key_columns=['zipcode'],
operations={'avg': graphlab.aggregate.MEAN('price')})
mean_by_zip.sort('avg', ascending=False)[0:3] # will give top 3
。希望它会对你有所帮助。