计算数组中不同且重复的属性值

时间:2010-05-16 19:37:23

标签: ruby-on-rails arrays struct count

我有一组用户,这些用户根据total_points按降序排序。

我需要找到该数组中每个用户的排名。问题是不止一个用户可以拥有相同的总分,因此具有相同的等级。例如,三个用户可以获得200分的第三名。这是我目前的代码:

class Leader < ActiveRecord::Base  
  def self.points_leaders
    all_leaders = all_points_leaders # returns array of users sorted by total_points in desc order
    all_leaders_with_rank = []

    all_leaders.each do |user|
      rank = all_leaders.index(user)+1
      all_leaders_with_rank << Ldr.new(rank, user) # Ldr is a Struct
    end

    return all_leaders_with_rank
  end
end

如何修改代码以便返回正确的排名,而不仅仅是索引位置的值?

2 个答案:

答案 0 :(得分:0)

borderline-brute-force方法只是对现有代码的简单更改。

rank = 1
all_leaders.each_with_index do |user, idx|
  # If this user has a different point total than the previous user in the list,
  # bump the rank.
  if idx > 0 && all_leaders[idx - 1].total_points != user.total_points
    # The point of using the idx as an offset here is so that you end up with 
    # T1
    # T1
    # T3
    # in the case of a tie for first.
    rank = idx + 1
  end
  all_leaders_with_rank << Ldr.new(rank, user) # Ldr is a Struct
end

答案 1 :(得分:0)

创建一个唯一点数组(按all_points_leaders函数排序)。使用该数组的索引+ 1作为用户的等级。

def self.points_leaders
  all_points = all_points_leaders.map {|user| user.total_points }.uniq
  all_points_leaders.map do |user|
    rank = all_points.index(user.total_points) + 1
    Ldr.new(rank, user)
  end
end