Skip to content

Commit 71ea0e9

Browse files
authored
Implement anyMatch allMatch and noneMatch for collections (#93)
1 parent 371049a commit 71ea0e9

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

src/Collection/Traversable.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,62 @@ public function filterNot(callable $predicate)
117117
});
118118
}
119119

120+
/**
121+
* Returns true if any element of this collection match the provided predicate.
122+
* May not evaluate the predicate on all elements if not necessary for determining the result.
123+
*
124+
* @param callable(T):bool $predicate
125+
*/
126+
public function anyMatch(callable $predicate): bool
127+
{
128+
$iterator = $this->getIterator();
129+
while ($iterator->hasNext()) {
130+
if ($predicate($iterator->next())) {
131+
return true;
132+
}
133+
}
134+
135+
return false;
136+
}
137+
138+
/**
139+
* Returns true if all elements of this collection match the provided predicate.
140+
* May not evaluate the predicate on all elements if not necessary for determining the result.
141+
* If collection is empty true is returned.
142+
*
143+
* @param callable(T):bool $predicate
144+
*/
145+
public function allMatch(callable $predicate): bool
146+
{
147+
$iterator = $this->getIterator();
148+
while ($iterator->hasNext()) {
149+
if (!$predicate($iterator->next())) {
150+
return false;
151+
}
152+
}
153+
154+
return true;
155+
}
156+
157+
/**
158+
* Returns true if no elements of this collection match the provided predicate.
159+
* May not evaluate the predicate on all elements if not necessary for determining the result.
160+
* If collection is empty true is returned.
161+
*
162+
* @param callable(T):bool $predicate
163+
*/
164+
public function noneMatch(callable $predicate): bool
165+
{
166+
$iterator = $this->getIterator();
167+
while ($iterator->hasNext()) {
168+
if ($predicate($iterator->next())) {
169+
return false;
170+
}
171+
}
172+
173+
return true;
174+
}
175+
120176
/**
121177
* Returns true if the two specified collections have no elements in common.
122178
*

tests/Collection/TraversableTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,34 @@ public function testCount(): void
115115

116116
self::assertEquals(1, Set::of('munus', 'is', 'awesome')->count(function (string $value) {return strpos($value, 'some') !== false; }));
117117
}
118+
119+
public function testAnyMatch(): void
120+
{
121+
self::assertTrue(GenericList::of(1, 2, 3, 4, 5)->anyMatch(fn (int $v) => $v === 1));
122+
self::assertTrue(GenericList::of(1, 2, 3, 4, 5)->anyMatch(fn (int $v) => $v === 3));
123+
self::assertTrue(GenericList::of(1, 2, 3, 4, 5)->anyMatch(fn (int $v) => $v === 5));
124+
125+
self::assertFalse(GenericList::of(1, 2, 3, 4, 5)->anyMatch(fn (int $v) => $v === 0));
126+
self::assertFalse(GenericList::empty()->anyMatch(fn (int $v) => $v === 0));
127+
}
128+
129+
public function testAllMatch(): void
130+
{
131+
self::assertTrue(GenericList::of(2, 4, 6, 8)->allMatch(fn (int $v) => $v % 2 === 0));
132+
self::assertTrue(GenericList::of(10, 12, 14, 16)->allMatch(fn (int $v) => $v % 2 === 0));
133+
self::assertTrue(GenericList::empty()->allMatch(fn (int $v) => $v % 2 === 1));
134+
135+
self::assertFalse(GenericList::of(2, 4, 6, 8)->allMatch(fn (int $v) => $v % 2 === 1));
136+
self::assertFalse(GenericList::of(0)->allMatch(fn (int $v) => $v % 2 === 1));
137+
}
138+
139+
public function testNoneMatch(): void
140+
{
141+
self::assertTrue(GenericList::of(2, 4, 6, 8)->noneMatch(fn (int $v) => $v % 2 === 1));
142+
self::assertTrue(GenericList::empty()->noneMatch(fn (int $v) => $v % 2 === 1));
143+
144+
self::assertFalse(GenericList::of(2, 4, 6, 8)->noneMatch(fn (int $v) => $v % 2 === 0));
145+
self::assertFalse(GenericList::of(1, 2, 3)->noneMatch(fn (int $v) => $v % 2 === 0));
146+
self::assertFalse(GenericList::of(1)->noneMatch(fn (int $v) => $v % 2 === 1));
147+
}
118148
}

0 commit comments

Comments
 (0)