Skip to content

Commit

Permalink
Introduce append(), prepend(), push(), unshift()
Browse files Browse the repository at this point in the history
Fixes #103
Fixes #107
Fixes #106
  • Loading branch information
sanmai committed Nov 7, 2022
1 parent d64f62c commit 0d3f3ae
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
78 changes: 78 additions & 0 deletions src/Standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use function array_filter;
use function array_flip;
use function array_map;
use function array_merge;
use function array_reduce;
use function array_shift;
use function array_slice;
Expand Down Expand Up @@ -72,6 +73,83 @@ public function __construct(iterable $input = null)
$this->pipeline = $input;
}

public function append(iterable $values = null): self
{
// Do we need to do anything here?
if ($this->willReplace($values)) {
return $this;
}

return $this->join($this->pipeline, $values);
}

public function push(...$vector): self
{
return $this->append($vector);
}

public function prepend(iterable $values = null): self
{
// Do we need to do anything here?
if ($this->willReplace($values)) {
return $this;
}

return $this->join($values, $this->pipeline);
}

public function unshift(...$vector): self
{
return $this->prepend($vector);
}

/**
* Utility method for appending/prepending methods.
*/
private function willReplace(iterable $values = null): bool
{
// Nothing needs to be done here.
if (null === $values || [] === $values) {
return true;
}

// No shortcuts are applicable if the pipeline was initialized.
if ([] !== $this->pipeline && null !== $this->pipeline) {
return false;
}

// Install an array as it is.
if (is_array($values)) {
$this->pipeline = $values;

return true;
}

// Else we use ownself to handle edge cases.
$this->pipeline = new self($values);

return true;
}

/**
* Utility method for appending/prepending methods.
*/
private function join(iterable $left, iterable $right): self
{
// We got two arrays, that's what we will use.
if (is_array($left) && is_array($right)) {
$this->pipeline = array_merge($left, $right);

return $this;
}

// Last, join the hard way.
return $this->map(function () use ($left, $right) {
yield from $left;
yield from $right;
});
}

/**
* An extra variant of `map` which unpacks arrays into arguments. Flattens inputs if no callback provided.
*
Expand Down
15 changes: 13 additions & 2 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,27 @@ function map(callable $func = null): Standard
return $pipeline->map($func);
}

function take(iterable $input = null): Standard
function take(iterable $input = null, iterable ...$inputs): Standard
{
return new Standard($input);
$pipeline = new Standard($input);

foreach ($inputs as $input) {
$pipeline->append($input);
}

return $pipeline;
}

function fromArray(array $input): Standard
{
return new Standard($input);
}

function fromValues(...$values): Standard
{
return new Standard($values);
}

function zip(iterable $base, iterable ...$inputs): Standard
{
$result = take($base);
Expand Down
20 changes: 20 additions & 0 deletions tests/FunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use function iterator_to_array;
use PHPUnit\Framework\TestCase;
use function Pipeline\fromArray;
use function Pipeline\fromValues;
use function Pipeline\map;
use Pipeline\Standard;
use function Pipeline\take;
Expand Down Expand Up @@ -81,6 +82,25 @@ public function testTakeArray(): void
$this->assertSame([1, 2, 3, 4, 5], take([1, 2, 3, 4, 5])->toArray());
}

/**
* @covers \Pipeline\take
*/
public function testTakeMany(): void
{
$this->assertSame([1, 2, 3, 4, 5], take([1, 2], [3, 4], [5])->toArray());

$this->assertSame([1, 2, 3, 4, 5], take(take([1, 2]), take([3, 4]), fromValues(5))->toArray());
}

/**
* @covers \Pipeline\fromValues
*/
public function testFromValues(): void
{
$this->assertSame([1, 2, 3, 4, 5], fromValues(1, 2, 3, 4, 5)->toArray());
$this->assertSame([1, 2, 3], fromValues(...[1, 2, 3])->toArray());
}

/**
* @covers \Pipeline\fromArray
*/
Expand Down

0 comments on commit 0d3f3ae

Please sign in to comment.