【Golang, TypeScript】期間の重複をマージする
はじめに
業務で期間の範囲を扱う際に、範囲の重複を考慮する必要がありました。
例として、以下のように範囲の重複があった場合、
最終的に以下のような期間の重複している範囲をマージした結果を求めているイメージです。
成果物
https://github.com/kntks/blog-code/tree/main/2023/02/merge-overlapping-inteval
TypeScript コード
まずはコードです。
重複する間隔のマージを参考にTypeScriptで書いてみました。
意図した結果になっていそうです!
簡単に解説
はじめにArray.prototype.map()を使ってintervalsから新しい配列を生成します。
理由は、後ろに続くArray.prototype.sort()が元の配列の順序を変えてしまうからです。
ソートされた元の配列への参照です。なお、配列はその場でソートされ、コピーは作成されません。
返値
続いてforEachの中を見てみます。
ここのifの条件ですが
配列stackにデータをpushしても良い条件は、以下の通りです。
- 配列が空である
- 比較対象期間の始まりの時間(curr.start)が、stack内にある一番遅い時間(top.end)よりも後ろにある
つまり、期間が重複していなければpushしてもいいよね、ということです。図で表すと以下になります。
最後の条件です。
処理がここまで到達しているということは、stack内の一番最後の期間(top)と比較対象の期間(curr)が重複することがわかっています。
最後の条件では、比較対象の期間はstack内の一番最後の期間(top)内なのかを確認しています。
図で表すと以下のどちらなのかを判定している、ということになります。
比較対象期間の最後の時間(curr.end)がstack内の一番遅い時間(top.end)も後ろにある場合は、top.endを更新して終わりです。
Go言語 コード
Go言語でも実装してみました。先ほどのTypeScriptのときと処理は同じです。
Go言語の場合は、time.Beforeの境界の挙動が怪しかったので、テストを書いて動作を確認しました。
まとめ
重複する期間のマージをTypeScript、Golangで実装しました。
今回作成したコードはkntks/blog-code/merge-overlapping-inteval - GitHubにあります。
参考になれば幸いです。