Skip to content

Commit

Permalink
[Collection] Set/NonEmptySet intersect and diff ops.
Browse files Browse the repository at this point in the history
  • Loading branch information
whsv26 committed Dec 24, 2021
1 parent 80a4a68 commit 5d534bf
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 17 deletions.
20 changes: 20 additions & 0 deletions src/Fp/Collections/HashSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,24 @@ public function subsetOf(Set|NonEmptySet $superset): bool

return $isSubset;
}

/**
* @inheritDoc
* @param Set<TV>|NonEmptySet<TV> $that
* @return Set<TV>
*/
public function intersect(Set|NonEmptySet $that): Set
{
return $this->filter(fn($elem) => /** @var TV $elem */ $that($elem));
}

/**
* @inheritDoc
* @param Set<TV>|NonEmptySet<TV> $that
* @return Set<TV>
*/
public function diff(Set|NonEmptySet $that): Set
{
return $this->filter(fn($elem) => /** @var TV $elem */ !$that($elem));
}
}
20 changes: 20 additions & 0 deletions src/Fp/Collections/NonEmptyHashSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -445,4 +445,24 @@ public function subsetOf(Set|NonEmptySet $superset): bool

return $isSubset;
}

/**
* @inheritDoc
* @param Set<TV>|NonEmptySet<TV> $that
* @return Set<TV>
*/
public function intersect(Set|NonEmptySet $that): Set
{
return $this->filter(fn($elem) => /** @var TV $elem */ $that($elem));
}

/**
* @inheritDoc
* @param Set<TV>|NonEmptySet<TV> $that
* @return Set<TV>
*/
public function diff(Set|NonEmptySet $that): Set
{
return $this->filter(fn($elem) => /** @var TV $elem */ !$that($elem));
}
}
30 changes: 30 additions & 0 deletions src/Fp/Collections/NonEmptySetChainableOps.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,34 @@ public function tap(callable $callback): NonEmptySet;
* @psalm-return Set<TV>
*/
public function tail(): Set;

/**
* Computes the intersection between this set and another set.
*
* ```php
* >>> NonEmptyHashSet::collectNonEmpty([1, 2, 3])
* ->intersect(HashSet::collect([2, 3]))->toArray();
* => [2, 3]
* ```
*
* @param Set<TV>|NonEmptySet<TV> $that the set to intersect with.
* @return Set<TV> a new set consisting of all elements that are both in this
* set and in the given set `that`.
*/
public function intersect(Set|NonEmptySet $that): Set;

/**
* Computes the difference of this set and another set.
*
* ```php
* >>> NonEmptyHashSet::collectNonEmpty([1, 2, 3])
* ->diff(HashSet::collect([2, 3]))->toArray();
* => [1]
* ```
*
* @param Set<TV>|NonEmptySet<TV> $that the set of elements to exclude.
* @return Set<TV> a set containing those elements of this
* set that are not also contained in the given set `that`.
*/
public function diff(Set|NonEmptySet $that): Set;
}
64 changes: 47 additions & 17 deletions src/Fp/Collections/SetChainableOps.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public function removed(mixed $element): Set;
* => [2]
* ```
*
* @psalm-param callable(TV): bool $predicate
* @psalm-return Set<TV>
* @param callable(TV): bool $predicate
* @return Set<TV>
*/
public function filter(callable $predicate): Set;

Expand All @@ -60,10 +60,10 @@ public function filter(callable $predicate): Set;
* => [Foo(2)]
* ```
*
* @psalm-template TVO
* @psalm-param class-string<TVO> $fqcn fully qualified class name
* @psalm-param bool $invariant if turned on then subclasses are not allowed
* @psalm-return Set<TVO>
* @template TVO
* @param class-string<TVO> $fqcn fully qualified class name
* @param bool $invariant if turned on then subclasses are not allowed
* @return Set<TVO>
*/
public function filterOf(string $fqcn, bool $invariant = false): Set;

Expand All @@ -75,7 +75,7 @@ public function filterOf(string $fqcn, bool $invariant = false): Set;
* => [1]
* ```
*
* @psalm-return Set<TV>
* @return Set<TV>
*/
public function filterNotNull(): Set;

Expand All @@ -92,9 +92,9 @@ public function filterNotNull(): Set;
* => [1, 2]
* ```
*
* @psalm-template TVO
* @psalm-param callable(TV): Option<TVO> $callback
* @psalm-return Set<TVO>
* @template TVO
* @param callable(TV): Option<TVO> $callback
* @return Set<TVO>
*/
public function filterMap(callable $callback): Set;

Expand All @@ -104,9 +104,9 @@ public function filterMap(callable $callback): Set;
* => [1, 2, 3, 4, 5, 6]
* ```
*
* @psalm-template TVO
* @psalm-param callable(TV): iterable<TVO> $callback
* @psalm-return Set<TVO>
* @template TVO
* @param callable(TV): iterable<TVO> $callback
* @return Set<TVO>
*/
public function flatMap(callable $callback): Set;

Expand All @@ -120,8 +120,8 @@ public function flatMap(callable $callback): Set;
* ```
*
* @template TVO
* @psalm-param callable(TV): TVO $callback
* @psalm-return Set<TVO>
* @param callable(TV): TVO $callback
* @return Set<TVO>
*/
public function map(callable $callback): Set;

Expand All @@ -137,7 +137,7 @@ public function map(callable $callback): Set;
* ```
*
* @param callable(TV): void $callback
* @psalm-return Set<TV>
* @return Set<TV>
*/
public function tap(callable $callback): Set;

Expand All @@ -149,7 +149,37 @@ public function tap(callable $callback): Set;
* => [2, 3]
* ```
*
* @psalm-return Set<TV>
* @return Set<TV>
*/
public function tail(): Set;

/**
* Computes the intersection between this set and another set.
*
* ```php
* >>> HashSet::collect([1, 2, 3])
* ->intersect(HashSet::collect([2, 3]))->toArray();
* => [2, 3]
* ```
*
* @param Set<TV>|NonEmptySet<TV> $that the set to intersect with.
* @return Set<TV> a new set consisting of all elements that are both in this
* set and in the given set `that`.
*/
public function intersect(Set|NonEmptySet $that): Set;

/**
* Computes the difference of this set and another set.
*
* ```php
* >>> HashSet::collect([1, 2, 3])
* ->diff(HashSet::collect([2, 3]))->toArray();
* => [1]
* ```
*
* @param Set<TV>|NonEmptySet<TV> $that the set of elements to exclude.
* @return Set<TV> a set containing those elements of this
* set that are not also contained in the given set `that`.
*/
public function diff(Set|NonEmptySet $that): Set;
}
17 changes: 17 additions & 0 deletions tests/Runtime/Interfaces/NonEmptySet/NonEmptySetOpsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,21 @@ public function testTail(): void
NonEmptyHashSet::collectNonEmpty([1, 2, 3])->tail()->toArray()
);
}

public function testIntersectAndDiff(): void
{
$this->assertEquals(
[2, 3],
NonEmptyHashSet::collectNonEmpty([1, 2, 3])
->intersect(HashSet::collect([2, 3]))
->toArray()
);

$this->assertEquals(
[1],
NonEmptyHashSet::collectNonEmpty([1, 2, 3])
->diff(HashSet::collect([2, 3]))
->toArray()
);
}
}
17 changes: 17 additions & 0 deletions tests/Runtime/Interfaces/Set/SetOpsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,21 @@ public function testTail(): void
HashSet::collect([1, 2, 3])->tail()->toArray()
);
}

public function testIntersectAndDiff(): void
{
$this->assertEquals(
[2, 3],
HashSet::collect([1, 2, 3])
->intersect(HashSet::collect([2, 3]))
->toArray()
);

$this->assertEquals(
[1],
HashSet::collect([1, 2, 3])
->diff(HashSet::collect([2, 3]))
->toArray()
);
}
}

0 comments on commit 5d534bf

Please sign in to comment.