Skip to content

Commit

Permalink
Add find method
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet committed Feb 15, 2021
1 parent a519bec commit 986fa6b
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 0 deletions.
12 changes: 12 additions & 0 deletions docs/en/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ Tests for the existence of an element that satisfies the given predicate.
return $value === 'first';
}); // true
findOne
-------

Returns the first element of this collection that satisfies the given predicate.

.. code-block:: php
$collection = new Collection([1, 2, 3, 2, 1]);
$one = $collection->findOne(function(int $key, int $value): bool {
return $value > 2 && $key > 1;
}); // 3
filter
------

Expand Down
7 changes: 7 additions & 0 deletions lib/Doctrine/Common/Collections/AbstractLazyCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ public function exists(Closure $p): bool
return $this->collection->exists($p);
}

public function findOne(Closure $func)
{
$this->initialize();

return $this->collection->findOne($func);
}

/**
* @return Collection<mixed>
*
Expand Down
11 changes: 11 additions & 0 deletions lib/Doctrine/Common/Collections/ArrayCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,17 @@ public function filter(Closure $p): Collection
return $this->createFrom(array_filter($this->elements, $p, ARRAY_FILTER_USE_BOTH));
}

public function findOne(Closure $p)
{
foreach ($this->elements as $key => $element) {
if ($p($key, $element)) {
return $element;
}
}

return null;
}

public function forAll(Closure $p): bool
{
foreach ($this->elements as $key => $element) {
Expand Down
13 changes: 13 additions & 0 deletions lib/Doctrine/Common/Collections/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,19 @@ public function next();
*/
public function exists(Closure $p): bool;

/**
* Returns the first element of this collection that satisfies the predicate p.
*
* @param Closure $p The predicate.
*
* @return mixed The first element respecting the predicate,
* null if no element respects the predicate.
*
* @psalm-param Closure(TKey=, T=):bool $p
* @psalm-return T|null
*/
public function findOne(Closure $p);

/**
* Returns all the elements of this collection that satisfy the predicate p.
* The order of the elements is preserved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,26 @@ public function testExists(): void
}), 'Element not exists');
}

public function testFindOne(): void
{
$elements = [1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'zero' => 0];
$collection = $this->buildCollection($elements);

self::assertSame('a', $collection->findOne(static function ($key, $element) {
return $key === 'A' && $element === 'a';
}), 'Element exists');
}

public function testFindOneNotFound(): void
{
$elements = [1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'zero' => 0];
$collection = $this->buildCollection($elements);

self::assertNull($collection->findOne(static function ($key, $element) {
return $key === 'non-existent' && $element === 'non-existent';
}), 'Element does not exists');
}

public function testIndexOf(): void
{
$elements = [1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'zero' => 0];
Expand Down
20 changes: 20 additions & 0 deletions tests/Doctrine/Tests/Common/Collections/BaseCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ public function testExists(): void
self::assertFalse($exists);
}

public function testFindOne(): void
{
$this->collection->add('one');
$this->collection->add('two');
$one = $this->collection->findOne(static function ($k, $e) {
return $e === 'one';
});
self::assertSame('one', $one);
}

public function testFindOneNotFound(): void
{
$this->collection->add('one');
$this->collection->add('two');
$other = $this->collection->findOne(static function ($k, $e) {
return $e === 'other';
});
self::assertNull($other);
}

public function testMap(): void
{
$this->collection->add(1);
Expand Down

0 comments on commit 986fa6b

Please sign in to comment.