Skip to content

Commit

Permalink
Add the Until operation with tests and example in README.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 14, 2019
1 parent debec59 commit 4c73fe4
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 2 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,23 @@ $string = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Collection::with($string)
->explode(' ')
->count(); // 71

// The Collatz conjecture (https://en.wikipedia.org/wiki/Collatz_conjecture)
$collatz = static function (int $initial = 1): int
{
return 0 === $initial % 2 ?
$initial / 2:
$initial * 3 + 1;
};

Collection::iterate($collatz, 10)
->until(static function ($number): bool {
return 1 === $number;
})
->all(); // [5, 16, 8, 4, 2, 1]



```

## Advanced usage
Expand Down Expand Up @@ -311,8 +328,8 @@ include 'vendor/autoload.php';
use drupol\collection\Base;
use drupol\collection\Contract\Allable;
use drupol\collection\Contract\Runable;
use drupol\collection\Operation\All;
use drupol\collection\Operation\Run;
use drupol\collection\Transformation\All;
use drupol\collection\Transformation\Run;
use drupol\collection\Contract\Operation;

$customCollectionClass = new class extends Base implements Allable {
Expand Down Expand Up @@ -389,6 +406,7 @@ the methods always return the same values for the same inputs.
| `slice` | new Collection object | [Slice.php](./src/Operation/Slice.php)
| `sort` | new Collection object | [Sort.php](./src/Operation/Sort.php)
| `split` | new Collection object | [Split.php](./src/Operation/Split.php)
| `until` | new Collection object | [Until.php](./src/Operation/Until.php)
| `walk` | new Collection object | [Walk.php](./src/Operation/Walk.php)
| `zip` | new Collection object | [Zip.php](./src/Operation/Zip.php)

Expand Down
20 changes: 20 additions & 0 deletions spec/drupol/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,26 @@ public function it_can_split(): void
->shouldIterateAs([0 => [1, 2, 3], 1 => [4, 5, 6], 2 => [7, 8, 9], 3 => [10, 11, 12], 4 => [13, 14, 15]]);
}

public function it_can_until(): void
{
$collatz = static function (int $initial = 1): int {
return 0 === $initial % 2 ?
$initial / 2 :
$initial * 3 + 1;
};

$this
->beConstructedThrough('iterate', [$collatz, 10]);

$until = static function (int $number): bool {
return 1 === $number;
};

$this
->until($until)
->shouldIterateAs([5, 16, 8, 4, 2, 1]);
}

public function it_can_use_range(): void
{
$this
Expand Down
11 changes: 11 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use drupol\collection\Operation\Slice;
use drupol\collection\Operation\Sort;
use drupol\collection\Operation\Split;
use drupol\collection\Operation\Until;
use drupol\collection\Operation\Walk;
use drupol\collection\Operation\Zip;
use drupol\collection\Transformation\All;
Expand Down Expand Up @@ -480,6 +481,16 @@ static function () use ($number) {
return null === $callback ? $instance : $instance->run(new Walk($callback));
}

/**
* {@inheritdoc}
*
* @return \drupol\collection\Contract\Collection
*/
public function until(callable $callback): BaseInterface
{
return $this->run(new Until($callback));
}

/**
* {@inheritdoc}
*
Expand Down
1 change: 1 addition & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ interface Collection extends
Sliceable,
Sortable,
Splitable,
Untilable,
Walkable,
Zipable
{
Expand Down
18 changes: 18 additions & 0 deletions src/Contract/Untilable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace drupol\collection\Contract;

/**
* Interface Untilable.
*/
interface Untilable
{
/**
* @param callable $callable
*
* @return \drupol\collection\Contract\Collection
*/
public function until(callable $callable): Base;
}
46 changes: 46 additions & 0 deletions src/Operation/Until.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace drupol\collection\Operation;

use drupol\collection\Contract\Operation;

/**
* Class Until.
*/
final class Until implements Operation
{
/**
* @var callable
*/
private $callable;

/**
* Until constructor.
*
* @param callable $until
*/
public function __construct(callable $until)
{
$this->callable = $until;
}

/**
* {@inheritdoc}
*/
public function on(iterable $collection): \Closure
{
$until = $this->callable;

return static function () use ($until, $collection): \Generator {
foreach ($collection as $key => $value) {
yield $key => $value;

if (true === $until($value, $key)) {
break;
}
}
};
}
}

0 comments on commit 4c73fe4

Please sign in to comment.