'Ruby On Rails sort the array of hash based on priority

Please help me finding the solution sort by based on priority Im not getting the solution

priority based on:

  • 1st pick earliest slot
  • 2nd max rating
  • 3rd cronofy_enabled
interview_proposal = [
  { interviewer_id: 3903, rating: 4, cronofy_enabled: false, slot_date: "2022-05-09" },
  { interviewer_id: 10, rating: 3.5, cronofy_enabled: false, slot_date: "2022-05-06" },
  { interviewer_id: 3902, rating: 2, cronofy_enabled: true, slot_date: "2022-05-06" },
{ interviewer_id: 3904, rating: 2.5, cronofy_enabled: false, slot_date: "2022-05-09" },
{ interviewer_id: 3905, rating: 3.5, cronofy_enabled: false, slot_date: "2022-05-09" }
]
    
# First priority picked earliest_slot
@earliest_slot = interview_proposal.find{|proposal| proposal[:slot_date] == "2022-05-06"}
#second priority rating
@max_rating = interview_proposal.max_by{|proposal| proposal[:rating]}
# Third priority cronofy_enabled
@calendar_synced = interview_proposal.find{|proposal| proposal[:cronofy_enabled]}
    
sorted_array = []
interview_proposal.each do |interview_proposal|
  priority = match_count
  sorted_array << { priority: priority, interview_proposal: interview_proposal }
end
sorted_array = sorted_array.
  sort_by { |obj| obj[:priority] }.
  reverse.map { |obj| obj[:interview_proposal] }
sorted_array
    
def match_count
  count = 0
  count += 1 if @earliest_slot[:slot_date].present?
  count += 1 if @max_rating[:rating].present?
  count += 1 if @calendar_synced[:cronofy_enabled]
  count
end


Solution 1:[1]

It seems to me you can reduce the overhead in your code by using Ruby's sort method. All you need to provide in each block iteration for the sort to work is a positive integer if a > b, 0 if they are equal and a negative integer if b >a. The starship operator <=> is a nice shortcut to use for the first two cases but does not work on booleans so we added the extra logic there.

sorted_array = interview_proposal.sort do |a, b|

   if  (a[:slot_date] <=> b[:slot_date]) != 0
      a[:slot_date] <=> b[:slot_date] 
   elsif (a[:rating] <=> b[:rating]) != 0
      a[:rating] <=> b[:rating]
   elsif a[:cronofy_enabled] == b[:cronofy_enabled]
       0
   elsif a[:cronofy_enabled]
       1
   else 
      -1
   end
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1