Skip to content

Commit

Permalink
Merge pull request #28 from Bl00D4NGEL/feat/add-find-method
Browse files Browse the repository at this point in the history
feat: add find and findLast functions
  • Loading branch information
Bl00D4NGEL authored Feb 9, 2024
2 parents 989debf + 01e2194 commit 337df9b
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 12 deletions.
10 changes: 1 addition & 9 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,4 @@ jobs:

# Run tests
- name: Run Unit Tests
run: |
vendor/bin/phpunit --coverage-text --coverage-clover reports/coverage.xml
# SonarCloud
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: vendor/bin/phpunit
39 changes: 38 additions & 1 deletion src/Domain/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
/**
* @template T of object
* @implements IteratorAggregate<T>
* @implements ArrayAccess<mixed, T>
* @implements ArrayAccess<array-key, T>
*/
class Collection implements ArrayAccess, Countable, IteratorAggregate
{
/**
* @param T[] $items
* @param class-string<T>|null $itemType
* @throws Assert\AssertionFailedException
*/
final public function __construct(
private readonly array $items = [],
Expand Down Expand Up @@ -131,6 +132,42 @@ public function some(callable $callback = null): bool
return false;
}

/**
* Returns the first element of the collection that matches the given callback or null if the collection is empty
* or the callback never returned true for any item
*
* @param callable(T, int, static): bool $callback
* @return ?T
*/
public function find(callable $callback)
{
foreach ($this->items as $index => $item) {
if ($callback($item, $index, $this)) {
return $item;
}
}

return null;
}

/**
* Returns the last element of the collection that matches the given callback or null if the collection is empty
* or the callback never returned true for any item
*
* @param callable(T, int, static): bool $callback
* @return ?T
*/
public function findLast(callable $callback)
{
foreach (array_reverse($this->items) as $index => $item) {
if ($callback($item, $index, $this)) {
return $item;
}
}

return null;
}

/**
* Returns the first element of the collection that matches the given callback.
* If no callback is given the first element in the collection is returned.
Expand Down
50 changes: 48 additions & 2 deletions tests/Domain/CollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,52 @@ public function testSomeShortCircuitsOnFirstFalsyValue(): void
});
}

public function testFind(): void
{
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$collection = new Collection($items);

$this->assertSame(3, $collection->find(static fn ($item) => $item > 2));
}

public function testFindReturnsNullIfCallbackNeverReturnsTrue(): void
{
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$collection = new Collection($items);

$this->assertSame(null, $collection->find(static fn () => false));
}

public function testFindReturnsNullOnEmptyCollection(): void
{
$collection = new Collection([]);

$this->assertSame(null, $collection->find(static fn () => true));
}

public function testFindLast(): void
{
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$collection = new Collection($items);

$this->assertSame(10, $collection->findLast(static fn ($item) => $item > 2));
}

public function testFindLastReturnsNullIfCallbackNeverReturnsTrue(): void
{
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$collection = new Collection($items);

$this->assertSame(null, $collection->findLast(static fn () => false));
}

public function testFindLastReturnsNullOnEmptyCollection(): void
{
$collection = new Collection([]);

$this->assertSame(null, $collection->find(static fn () => true));
}

public function testFirst(): void
{
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Expand Down Expand Up @@ -477,7 +523,7 @@ public function testFirstOrReturnsFallbackValueIfCallbackIsNeverSatisfied(): voi
{
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$collection = new Collection($items);
$this->assertSame(-1, $collection->firstOr(static fn ($item) => $item > 10, -1));
$this->assertSame(-1, $collection->firstOr(static fn () => false, -1));
}

public function testLast(): void
Expand Down Expand Up @@ -524,7 +570,7 @@ public function testLastOrReturnsFallbackValueIfCallbackIsNeverSatisfied(): void
{
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$collection = new Collection($items);
$this->assertSame(-1, $collection->lastOr(static fn ($item) => $item > 10, -1));
$this->assertSame(-1, $collection->lastOr(static fn () => false, -1));
}

public function testIsEmpty(): void
Expand Down

0 comments on commit 337df9b

Please sign in to comment.