Skip to content

Commit 337df9b

Browse files
authored
Merge pull request #28 from Bl00D4NGEL/feat/add-find-method
feat: add find and findLast functions
2 parents 989debf + 01e2194 commit 337df9b

File tree

3 files changed

+87
-12
lines changed

3 files changed

+87
-12
lines changed

.github/workflows/tests.yml

+1-9
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,4 @@ jobs:
3838

3939
# Run tests
4040
- name: Run Unit Tests
41-
run: |
42-
vendor/bin/phpunit --coverage-text --coverage-clover reports/coverage.xml
43-
44-
# SonarCloud
45-
- name: SonarCloud Scan
46-
uses: SonarSource/sonarcloud-github-action@master
47-
env:
48-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49-
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
41+
run: vendor/bin/phpunit

src/Domain/Collection.php

+38-1
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
/**
2424
* @template T of object
2525
* @implements IteratorAggregate<T>
26-
* @implements ArrayAccess<mixed, T>
26+
* @implements ArrayAccess<array-key, T>
2727
*/
2828
class Collection implements ArrayAccess, Countable, IteratorAggregate
2929
{
3030
/**
3131
* @param T[] $items
3232
* @param class-string<T>|null $itemType
33+
* @throws Assert\AssertionFailedException
3334
*/
3435
final public function __construct(
3536
private readonly array $items = [],
@@ -131,6 +132,42 @@ public function some(callable $callback = null): bool
131132
return false;
132133
}
133134

135+
/**
136+
* Returns the first element of the collection that matches the given callback or null if the collection is empty
137+
* or the callback never returned true for any item
138+
*
139+
* @param callable(T, int, static): bool $callback
140+
* @return ?T
141+
*/
142+
public function find(callable $callback)
143+
{
144+
foreach ($this->items as $index => $item) {
145+
if ($callback($item, $index, $this)) {
146+
return $item;
147+
}
148+
}
149+
150+
return null;
151+
}
152+
153+
/**
154+
* Returns the last element of the collection that matches the given callback or null if the collection is empty
155+
* or the callback never returned true for any item
156+
*
157+
* @param callable(T, int, static): bool $callback
158+
* @return ?T
159+
*/
160+
public function findLast(callable $callback)
161+
{
162+
foreach (array_reverse($this->items) as $index => $item) {
163+
if ($callback($item, $index, $this)) {
164+
return $item;
165+
}
166+
}
167+
168+
return null;
169+
}
170+
134171
/**
135172
* Returns the first element of the collection that matches the given callback.
136173
* If no callback is given the first element in the collection is returned.

tests/Domain/CollectionTest.php

+48-2
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,52 @@ public function testSomeShortCircuitsOnFirstFalsyValue(): void
433433
});
434434
}
435435

436+
public function testFind(): void
437+
{
438+
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
439+
$collection = new Collection($items);
440+
441+
$this->assertSame(3, $collection->find(static fn ($item) => $item > 2));
442+
}
443+
444+
public function testFindReturnsNullIfCallbackNeverReturnsTrue(): void
445+
{
446+
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
447+
$collection = new Collection($items);
448+
449+
$this->assertSame(null, $collection->find(static fn () => false));
450+
}
451+
452+
public function testFindReturnsNullOnEmptyCollection(): void
453+
{
454+
$collection = new Collection([]);
455+
456+
$this->assertSame(null, $collection->find(static fn () => true));
457+
}
458+
459+
public function testFindLast(): void
460+
{
461+
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
462+
$collection = new Collection($items);
463+
464+
$this->assertSame(10, $collection->findLast(static fn ($item) => $item > 2));
465+
}
466+
467+
public function testFindLastReturnsNullIfCallbackNeverReturnsTrue(): void
468+
{
469+
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
470+
$collection = new Collection($items);
471+
472+
$this->assertSame(null, $collection->findLast(static fn () => false));
473+
}
474+
475+
public function testFindLastReturnsNullOnEmptyCollection(): void
476+
{
477+
$collection = new Collection([]);
478+
479+
$this->assertSame(null, $collection->find(static fn () => true));
480+
}
481+
436482
public function testFirst(): void
437483
{
438484
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
@@ -477,7 +523,7 @@ public function testFirstOrReturnsFallbackValueIfCallbackIsNeverSatisfied(): voi
477523
{
478524
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
479525
$collection = new Collection($items);
480-
$this->assertSame(-1, $collection->firstOr(static fn ($item) => $item > 10, -1));
526+
$this->assertSame(-1, $collection->firstOr(static fn () => false, -1));
481527
}
482528

483529
public function testLast(): void
@@ -524,7 +570,7 @@ public function testLastOrReturnsFallbackValueIfCallbackIsNeverSatisfied(): void
524570
{
525571
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
526572
$collection = new Collection($items);
527-
$this->assertSame(-1, $collection->lastOr(static fn ($item) => $item > 10, -1));
573+
$this->assertSame(-1, $collection->lastOr(static fn () => false, -1));
528574
}
529575

530576
public function testIsEmpty(): void

0 commit comments

Comments
 (0)