2010-05-16 2 views
0

У меня есть массив пользователей, отсортированный по убыванию в зависимости от 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 

Как я должен изменить код так, что правильный ранг возвращается, а не только значение позиции индекса?

ответ

0

Пограничный подход с грубой силой будет простым изменением существующего кода.

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 
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 
Смежные вопросы