使用 Elixir 过滤重叠的时间段
Filter overlapping time periods using Elixir
我有两个包含开始时间和结束时间的元组列表。所有开始和结束时间都是 Time
结构。
我想过滤掉与 booked_slots
:
重叠的 time_slots
time_slots = [
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[21:00:00]},
{~T[17:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[13:00:00]},
{~T[09:00:00], ~T[21:00:00]}
]
booked_slots = [{~T[14:00:00], ~T[21:00:00]}]
应该留给我们的是:
[
{~T[09:00:00], ~T[13:00:00]}
]
我尝试了以下方法(改编自对先前相关问题的回答:):
Enum.filter(time_slots, fn {time_start, time_end} ->
Enum.any?(booked_slots, fn {booking_start, booking_end} ->
if Time.compare(booking_start, time_start) == :lt do
Time.compare(booking_end, time_start) == :gt
else
Time.compare(booking_start, time_end) == :lt
end
end)
end)
但是这个 returns:
[
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[21:00:00]},
{~T[17:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[21:00:00]}
]
我们还需要考虑可能相等但不重叠的时间。例如:
time_slots = [
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[21:00:00]},
{~T[17:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[13:00:00]}
]
booked_slots = [{~T[17:00:00], ~T[21:00:00]}]
应该return…
[
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[09:00:00], ~T[13:00:00]}
]
您需要过滤掉所有在预订时段内有开始或结束时间的时段。
Enum.reject(time_slots, fn {ts, te} ->
Enum.any?(booked_slots, fn {bs, be} ->
(Time.compare(ts, bs) != :lt and Time.compare(ts, be) == :lt) or
(Time.compare(te, bs) == :gt and Time.compare(te, be) != :gt) or
(Time.compare(ts, bs) == :lt and Time.compare(te, be) == :gt)
end)
end)
第一个条件检查开始时间在预订时段内的时段,第二个条件检查结束时间在预订时段内的时段,第三个条件检查包含整个预订时段的时段。
我有两个包含开始时间和结束时间的元组列表。所有开始和结束时间都是 Time
结构。
我想过滤掉与 booked_slots
:
time_slots
time_slots = [
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[21:00:00]},
{~T[17:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[13:00:00]},
{~T[09:00:00], ~T[21:00:00]}
]
booked_slots = [{~T[14:00:00], ~T[21:00:00]}]
应该留给我们的是:
[
{~T[09:00:00], ~T[13:00:00]}
]
我尝试了以下方法(改编自对先前相关问题的回答:
Enum.filter(time_slots, fn {time_start, time_end} ->
Enum.any?(booked_slots, fn {booking_start, booking_end} ->
if Time.compare(booking_start, time_start) == :lt do
Time.compare(booking_end, time_start) == :gt
else
Time.compare(booking_start, time_end) == :lt
end
end)
end)
但是这个 returns:
[
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[21:00:00]},
{~T[17:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[21:00:00]}
]
我们还需要考虑可能相等但不重叠的时间。例如:
time_slots = [
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[21:00:00]},
{~T[17:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[21:00:00]},
{~T[09:00:00], ~T[13:00:00]}
]
booked_slots = [{~T[17:00:00], ~T[21:00:00]}]
应该return…
[
{~T[09:00:00], ~T[17:00:00]},
{~T[13:00:00], ~T[17:00:00]},
{~T[09:00:00], ~T[13:00:00]}
]
您需要过滤掉所有在预订时段内有开始或结束时间的时段。
Enum.reject(time_slots, fn {ts, te} ->
Enum.any?(booked_slots, fn {bs, be} ->
(Time.compare(ts, bs) != :lt and Time.compare(ts, be) == :lt) or
(Time.compare(te, bs) == :gt and Time.compare(te, be) != :gt) or
(Time.compare(ts, bs) == :lt and Time.compare(te, be) == :gt)
end)
end)
第一个条件检查开始时间在预订时段内的时段,第二个条件检查结束时间在预订时段内的时段,第三个条件检查包含整个预订时段的时段。