Ruby: Compare two arrays for matches, and order results in DESC order
I have a user model. Each user has restaurant names associated with them. I have a view (index.html.erb) which shows all users.
I want to order the users in this view based on how many restaurants the current_user and some other user have in common in descending order... (it does the opposite!)
ex.
User1 (current_user) has been to McDonalds, Burger King, Arby'开发者_如何学Cs
User2 has been to Ivar's
User3 has been to McDonalds, Burger King
When User1 loads the index view, the order the users should be displayed is:
User1 (3/3 restaurants match)
User3 (2/3 restaurants match)
User2 (0/3 restaurants match)
my User.rb file
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
If you're dead set on using sort_by
then you can just negate the numbers:
def index
@users = User.all.sort_by { |el|
-(el.compare_resturants & current_user.compare_resturants).length
}
end
This trick only works because you're sorting by numeric values. If you were sorting on strings then you'd have to use something like this:
reverse_sorted = a.sort_by { |x| something(x) }.reverse
but that would involve an extra copy of the array and the extra work that reverse
would do. In such cases you should use a full sort
with reversed comparison logic.
If you're were trying to use sort_by
to avoid computing something expensive for each comparison and you were sorting on something non-numeric, then you could always use sort
with an explicit Schwartzian Transform to compute the expensive things only once.
Just sort them in the controller.
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
... but if you're planning on letting the user start sorting various columns or reversing the sorting a lot, you should implement your sort in Javascript so you can cut down on the number of page reloads and subsequent database hits you have to make.
精彩评论