Skip to content

Commit

Permalink
Add the Cycle operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 10, 2019
1 parent 6f4cddf commit b82b610
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 0 deletions.
19 changes: 19 additions & 0 deletions spec/drupol/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,25 @@ public function it_can_count_its_items(): void
->shouldReturn(3);
}

public function it_can_cycle(): void
{
$this
->beConstructedThrough('with', [['1', '2', '3']]);

$this
->cycle(1)
->shouldIterateAs(['1', '2', '3']);

$this
->cycle(2)
->shouldIterateAs(['1', '2', '3', '1', '2', '3']);

$this
->cycle()
->limit(7)
->shouldIterateAs(['1', '2', '3', '1', '2', '3', '1']);
}

public function it_can_distinct(): void
{
$stdclass = new \stdClass();
Expand Down
11 changes: 11 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use drupol\collection\Operation\Chunk;
use drupol\collection\Operation\Collapse;
use drupol\collection\Operation\Combine;
use drupol\collection\Operation\Cycle;
use drupol\collection\Operation\Distinct;
use drupol\collection\Operation\Explode;
use drupol\collection\Operation\Filter;
Expand Down Expand Up @@ -123,6 +124,16 @@ public function count(): int
return $this->transform(new Count());
}

/**
* {@inheritdoc}
*
* @return \drupol\collection\Contract\Collection
*/
public function cycle(int $count = 0): BaseInterface
{
return new Collection($this->run(new Cycle($count)));
}

/**
* {@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 @@ -16,6 +16,7 @@ interface Collection extends
Collapseable,
Combineable,
Containsable,
Cycleable,
Distinctable,
Explodeable,
Filterable,
Expand Down
18 changes: 18 additions & 0 deletions src/Contract/Cycleable.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 Cycleable.
*/
interface Cycleable
{
/**
* @param int $count
*
* @return \drupol\collection\Contract\Collection
*/
public function cycle(int $count = 0): Base;
}
44 changes: 44 additions & 0 deletions src/Operation/Cycle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace drupol\collection\Operation;

use drupol\collection\Contract\Operation;

/**
* Class Cycle.
*/
final class Cycle implements Operation
{
/**
* @var int
*/
private $count;

/**
* Cycle constructor.
*
* @param int $count
*/
public function __construct(int $count = 0)
{
$this->count = $count;
}

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

return static function () use ($collection, $count) {
for ($j = 0 === $count ? 1 : 0; $j !== $count; ++$j) {
foreach ($collection as $value) {
yield $value;
}
}
};
}
}

0 comments on commit b82b610

Please sign in to comment.