Объедините массив часов магазина торговца, которые перекрываются, чтобы произвести один диапазон
У меня есть список часов магазина от продавца, который потенциально может перекрываться, хранится в AvailableHours
модель. Модель имеет start_time
и end_time
хранится как TimeOfDay
объект ( https://github.com/JackC/tod).
Я хочу перебрать список и сравнить часы работы магазина, чтобы я мог просто отобразить 1 магазинный час. Например, если магазин мог иметь часы Mon: 9am-2pm
а также Mon: 10am-5pm
Я хотел бы отобразить Mon: 9am-5pm
, Магазин также может иметь два раза за один день, то есть Fri: 9-5pm, 7pm-10pm
, Я должен сделать это для каждого дня недели.
Проблема, с которой я сталкиваюсь, заключается в том, что моим кодом становится трудно управлять - я начал вводить множество вложенных if/else для ручной проверки (что кошмар!), Но мой вопрос таков:
Есть ли способ использовать ActiveRecord для создания хэша с объединенными временными диапазонами?
def ranges_overlap?(shift, current_shift)
shift.include?(current_shift.beginning) || current_shift.include?(shift.beginning)
end
def merge_ranges(shift, current_shift)
new_open_time = [shift.beginning, current_shift.beginning].min
new_close_time = [shift.ending, current_shift.ending].max
Shift.new(new_open_time, new_close_time)
end
def get_aggregate_merchant_hours
merchant = self
day = nil
shifts_array = []
output_shift_array = []
merchant_shifts = merchant_shifts = merchant.available_hours.order(day: :asc, open_time: :desc).map do |ah|
merged_shift = nil
show_output = false
# if it's a new day
if day.blank? || day != ah.day
output_shift_array = shifts_array
shifts_array = []
show_output = true if !day.blank?
output_day = day
day = ah.day
end
next if ah.open_time.blank? || ah.close_time.blank?
open_time = ah.open_time
close_time = ah.close_time
current_shift = Shift.new(open_time, close_time)
if !shifts_array.blank?
#compare and merge
shifts_array.each do |shift|
merged_shift = merge_ranges(shift, current_shift) if ranges_overlap?(shift, current_shift)
end
end
#replace old shift with merged shift
if merged_shift
delete_shift = shifts_array.find(beginning: current_shift.beginning, ending: current_shift.ending).first
shifts_array.delete(delete_shift) if delete_shift
shifts_array.push(merged_shift)
else
shifts_array.push(current_shift)
end
if show_output
store_hours_string = ""
if output_shift_array.blank?
store_hours_string = "Closed"
else
output_shift_array.each do |shift|
shift.beginning.strftime("%I:%M%p")
shift.ending.strftime("%I:%M%p")
if store_hours_string.blank?
store_hours_string << "#{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
else
store_hours_string << ", #{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
end
end
end
"#{Date::DAYNAMES[output_day][0..2]}: #{store_hours_string}"
end
end
#output last shift
store_hours_string = ""
if output_shift_array.blank?
store_hours_string = "Closed"
else
output_shift_array.each do |shift|
shift.beginning.strftime("%I:%M%p")
shift.ending.strftime("%I:%M%p")
if store_hours_string.blank?
store_hours_string << "#{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
else
store_hours_string << ", #{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
end
end
end
merchant_shifts << "#{Date::DAYNAMES[day][0..2]}: #{store_hours_string}"
merchant_shifts.compact
end