予定と予定がダブルブッキングしていないかどうか判定したい

1 min read読了の目安(約1700字

何度やっても忘れてしまう・・・下のような状況で isDoubleBooking がどのように実装されるべきか・・・?

let l = {
  start_at: new Date(2021, 1, 1),
  end_at: new Date(2021, 2, 1),
}

let r = {
  start_at: new Date(2021, 1, 16),
  end_at: new Date(2021, 2, 16),
}

function isDoubleBooking(l, r) {
  // TODO
}

ダブルブッキングを判定するコードを書いている人のポーズ

こんなふうにして手を左右に動かしている人がいたらきっとそういうこと考えているんだと思う。このために引数を lr にしてみた。

小指と小指の比較、親指と親指の比較

l の start_at と r の end_at、
r の start_at と l の end_at をそれぞれ比較すること。

つまり、
左手の小指と右手の小指、
右手の親指と左手の親指をそれぞれ比較すること。

不等号は < だけを使う

とくに今回の問題に限らずともこの癖をつけている人は多そう。

手を左右に動かしながらいろいろ確認する

すると、これが答えじゃないかと思う。

左手の小指 < 右手の小指 AND 右手の親指 < 左手の親指

これを翻訳して

l.start_at < r.end_at && r.start_at < l.end_at
function isDoubleBooking(l, r) {
  return l.start_at < r.end_at && r.start_at < l.end_at;
}

isDoubleBooking({
  start_at: new Date(2021, 1, 1),
  end_at: new Date(2021, 2, 1),
}, {
  start_at: new Date(2021, 2, 1),
  end_at: new Date(2021, 3, 1),
});

isDoubleBooking({
  start_at: new Date(2021, 1, 1),
  end_at: new Date(2021, 2, 1),
}, {
  start_at: new Date(2021, 1, 16),
  end_at: new Date(2021, 2, 16),
});

isDoubleBooking({
  start_at: new Date(2021, 1, 1),
  end_at: new Date(2021, 2, 1),
}, {
  start_at: new Date(2021, 1, 1),
  end_at: new Date(2021, 2, 1),
});

isDoubleBooking({
  start_at: new Date(2021, 1, 16),
  end_at: new Date(2021, 2, 16),
}, {
  start_at: new Date(2021, 2, 1),
  end_at: new Date(2021, 3, 1),
}); 

isDoubleBooking({
  start_at: new Date(2021, 2, 1),
  end_at: new Date(2021, 3, 16),
}, {
  start_at: new Date(2021, 1, 1),
  end_at: new Date(2021, 2, 1),
}); 

ふたつの予定を右手と左手に対応づけると、比較が親指どうし、小指どうしになるのが覚えやすいな、と思った。