Ruby: сравните два массива для совпадений и упорядочите результаты в порядке DESC - PullRequest
2 голосов
/ 18 февраля 2011

У меня есть модель пользователя. С каждым пользователем связаны названия ресторанов. У меня есть представление (index.html.erb), которое показывает всех пользователей.

Я хочу упорядочить пользователей в этом представлении, основываясь на том, сколько ресторанов current_user и некоторых других пользователей имеют общее в порядке убывания ... (это наоборот!)


отл.

Пользователь1 (current_user) был в Макдональдсе, Бургер Кинге, Арби

Пользователь2 был у Ивара

Пользователь 3 был в Макдональдсе, Бургер Кинг


Когда Пользователь1 загружает представление индекса, порядок отображения пользователей должен быть следующим:

Пользователь1 (соответствует 3/3 ресторана)

Пользователь3 (2/3 совпадения ресторанов)

Пользователь2 (0/3 совпадения ресторанов)


мой файл User.rb

def compare_restaurants
  self.restaurants.collect
end

my users_controller.rb

def index
  @users = User.all.sort_by {|el| (el.compare_resturants & current_user.compare_resturants).length }
end

Ответы [ 2 ]

4 голосов
/ 18 февраля 2011

Если вы не используете sort_by, то можете просто отменить числа:

def index
  @users = User.all.sort_by { |el|
    -(el.compare_resturants & current_user.compare_resturants).length
  }
end

Этот прием работает только потому, что вы сортируете по числовым значениям. Если бы вы сортировали строки, вам пришлось бы использовать что-то вроде этого:

reverse_sorted = a.sort_by { |x| something(x) }.reverse

но это потребует дополнительной копии массива и дополнительной работы, которую reverse сделает. В таких случаях вы должны использовать полный sort с обратной логикой сравнения.

Если вы пытались использовать sort_by, чтобы избежать вычисления чего-то дорогостоящего для каждого сравнения, и вы сортировали что-то не числовое, то вы всегда могли бы использовать sort с явным преобразованием Шварца вычислять дорогие вещи только один раз.

0 голосов
/ 18 февраля 2011

Просто отсортируйте их в контроллере.

my = User.find_by_id this_user  # Or however you're getting "the current user"
@users = User.all.-([my]).sort do |a, b|
  common_with_a = (my.restaurants & a.restaurants).length
  common_with_b = (my.restaurants & b.restaurants).length
  common_with_a <=> common_with_b
end

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...