Skip to content

Commit

Permalink
Add Intersperse method/operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Aug 21, 2019
1 parent d8e0c79 commit 913aa8c
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
52 changes: 52 additions & 0 deletions spec/drupol/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,58 @@ public function it_can_get_the_last_item(): void
->shouldReturn(null);
}

public function it_can_intersperse(): void
{
$this
->beConstructedThrough('with', [\range('A', 'F')]);

$this
->intersperse('foo', 2, 0)
->shouldIterateAs([
0 => 'foo',
1 => 'A',
2 => 'B',
3 => 'foo',
4 => 'C',
5 => 'D',
6 => 'foo',
7 => 'E',
8 => 'F',
]);

$this
->intersperse('foo', 2, 1)
->shouldIterateAs([
0 => 'A',
1 => 'foo',
2 => 'B',
3 => 'C',
4 => 'foo',
5 => 'D',
6 => 'E',
7 => 'foo',
8 => 'F',
]);

$this
->intersperse('foo', 2, 2)
->shouldIterateAs([
0 => 'foo',
1 => 'A',
2 => 'B',
3 => 'foo',
4 => 'C',
5 => 'D',
6 => 'foo',
7 => 'E',
8 => 'F',
]);

$this
->shouldThrow(\Exception::class)
->during('intersperse', ['foo', -1, 1]);
}

public function it_can_keys(): void
{
$this
Expand Down
9 changes: 9 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use drupol\collection\Operation\Flip;
use drupol\collection\Operation\Forget;
use drupol\collection\Operation\Get;
use drupol\collection\Operation\Intersperse;
use drupol\collection\Operation\Keys;
use drupol\collection\Operation\Last;
use drupol\collection\Operation\Limit;
Expand Down Expand Up @@ -182,6 +183,14 @@ public function getIterator()
return $this->makeIterator($this->source);
}

/**
* {@inheritdoc}
*/
public function intersperse($element, int $every = 1, int $startAt = 0): CollectionInterface
{
return $this->run(Intersperse::with($element, $every, $startAt));
}

/**
* {@inheritdoc}
*/
Expand Down
12 changes: 12 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ public function get($key, $default = null);
*/
public function getIterator();

/**
* Insert a given value between each element of a collection.
* Indices are not preserved.
*
* @param mixed $element
* @param int $every
* @param int $startAt
*
* @return \drupol\collection\Contract\Collection
*/
public function intersperse($element, int $every = 1, int $startAt = 0): self;

/**
* Get the keys of the items.
*
Expand Down
44 changes: 44 additions & 0 deletions src/Operation/Intersperse.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\Collection;
use drupol\collection\Contract\Collection as CollectionInterface;

/**
* Class Intersperse.
*
* Insert a given value between each element of a collection.
* Indices are not preserved.
*/
final class Intersperse extends Operation
{
/**
* {@inheritdoc}
*/
public function run(CollectionInterface $collection): CollectionInterface
{
[$element, $every, $startAt] = $this->parameters;

if (0 >= $every) {
throw new \InvalidArgumentException('The parameter must be greater than zero.');
}

return Collection::with(
static function () use ($element, $every, $startAt, $collection): \Generator {
$i = $startAt;

foreach ($collection as $key => $value) {
if (0 === $i % $every) {
yield $element;
}

yield $value;
++$i;
}
}
);
}
}

0 comments on commit 913aa8c

Please sign in to comment.