From 759397e662d65db0ed41c9a351b3b2949535ad99 Mon Sep 17 00:00:00 2001 From: Lukasz Przybyslawski Date: Thu, 24 Nov 2022 20:40:51 +0100 Subject: [PATCH] Implement PeriodCollection Union --- README.md | 6 ++++++ docs/img/collection-union.png | Bin 0 -> 25301 bytes src/PeriodCollection.php | 11 +++++++++++ tests/PeriodCollectionTest.php | 21 +++++++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 docs/img/collection-union.png diff --git a/README.md b/README.md index e7b0ee2..a0be6da 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,12 @@ Intersects given period with every period within a collection. The result is a n ![](./docs/img/collection-intersect.png) +### `union(): static` + +Merges all periods in collection with overlapping ranges. + +![](./docs/img/collection-union.png) + --- Finally, there are a few utility methods available on `PeriodCollection` as well: diff --git a/docs/img/collection-union.png b/docs/img/collection-union.png new file mode 100644 index 0000000000000000000000000000000000000000..872699061d168bb06743f8053f61ba518fb51471 GIT binary patch literal 25301 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 A+5i9m literal 0 HcmV?d00001 diff --git a/src/PeriodCollection.php b/src/PeriodCollection.php index 1728e23..0412810 100644 --- a/src/PeriodCollection.php +++ b/src/PeriodCollection.php @@ -200,4 +200,15 @@ public function sort(): PeriodCollection return $collection; } + + public function union(): PeriodCollection + { + $boundaries = $this->boundaries(); + + if (!$boundaries) { + return static::make(); + } + + return static::make($boundaries)->subtract($boundaries->subtract(...$this)); + } } diff --git a/tests/PeriodCollectionTest.php b/tests/PeriodCollectionTest.php index 8fd3563..c947371 100644 --- a/tests/PeriodCollectionTest.php +++ b/tests/PeriodCollectionTest.php @@ -284,3 +284,24 @@ expect($sorted[2]->equals($periods[2]))->toBeTrue(); expect($sorted[3]->equals($periods[3]))->toBeTrue(); }); + +it('unions collection', function () { + $collection = new PeriodCollection( + Period::make('2018-01-30', '2018-01-31'), + Period::make('2018-01-30', '2018-02-2'), + Period::make('2018-02-04', '2018-02-05'), + Period::make('2018-02-07', '2018-02-09'), + Period::make('2018-02-12', '2018-02-14'), + Period::make('2018-02-08', '2018-02-13') + ); + + $unioned = $collection->union(); + + expect($unioned)->toHaveCount(3); + expect($unioned[0]->start() == $collection[0]->start())->toBeTrue(); + expect($unioned[0]->end() == $collection[1]->end())->toBeTrue(); + expect($unioned[1]->start() == $collection[2]->start())->toBeTrue(); + expect($unioned[1]->end() == $collection[2]->end())->toBeTrue(); + expect($unioned[2]->start() == $collection[3]->start())->toBeTrue(); + expect($unioned[2]->end() == $collection[4]->end())->toBeTrue(); +});