Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add plus operation #314

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,16 @@ parameters:
count: 1
path: src/Operation/Map.php

-
message: "#^Template type U of method loophp\\\\collection\\\\Operation\\\\Plus\\:\\:__invoke\\(\\) is not referenced in a parameter\\.$#"
count: 1
path: src/Operation/Plus.php

-
message: "#^Template type UKey of method loophp\\\\collection\\\\Operation\\\\Plus\\:\\:__invoke\\(\\) is not referenced in a parameter\\.$#"
count: 1
path: src/Operation/Plus.php

-
message: "#^Template type U of method loophp\\\\collection\\\\Operation\\\\Prepend\\:\\:__invoke\\(\\) is not referenced in a parameter\\.$#"
count: 1
Expand Down
5 changes: 5 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
<code><![CDATA[Closure(bool): Closure(iterable<TKey, T>): (Generator<int, T>|Generator<TKey, T>)]]></code>
</InvalidReturnType>
</file>
<file src="src/Operation/Plus.php">
<InvalidArgument>
<code>$key</code>
</InvalidArgument>
</file>
<file src="src/Operation/Product.php">
<InvalidArgument>
<code>[[]]</code>
Expand Down
5 changes: 5 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,11 @@ public function pluck(mixed $pluck, mixed $default = null): CollectionInterface
return new self((new Operation\Pluck())()($pluck)($default), [$this]);
}

public function plus(iterable $items): CollectionInterface
{
return new self((new Operation\Plus())()($items), [$this]);
}

public function prepend(mixed ...$items): CollectionInterface
{
return new self((new Operation\Prepend())()($items), [$this]);
Expand Down
5 changes: 5 additions & 0 deletions src/CollectionDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,11 @@ public function pluck(mixed $pluck, mixed $default = null): static
return new static($this->innerCollection->pluck($pluck, $default));
}

public function plus(iterable $items): static
{
return new static($this->innerCollection->plus($items));
}

public function prepend(mixed ...$items): static
{
return new static($this->innerCollection->prepend(...$items));
Expand Down
2 changes: 2 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
* @template-extends Operation\Permutateable<TKey, T>
* @template-extends Operation\Pipeable<TKey, T>
* @template-extends Operation\Pluckable<TKey, T>
* @template-extends Operation\Plusable<TKey, T>
* @template-extends Operation\Prependable<TKey, T>
* @template-extends Operation\Productable<TKey, T>
* @template-extends Operation\Randomable<TKey, T>
Expand Down Expand Up @@ -213,6 +214,7 @@ interface Collection extends
Operation\Permutateable,
Operation\Pipeable,
Operation\Pluckable,
Operation\Plusable,
Operation\Prependable,
Operation\Productable,
Operation\Randomable,
Expand Down
28 changes: 28 additions & 0 deletions src/Contract/Operation/Plusable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Contract\Operation;

use loophp\collection\Contract\Collection;

/**
* @template TKey
* @template T
*/
interface Plusable
{
/**
* TODO - Plus items.
*
* @see https://loophp-collection.readthedocs.io/en/stable/pages/api.html#plus
*
* @template UKey
* @template U
*
* @param iterable<UKey, U> $items
*
* @return Collection<int|TKey|UKey, T|U>
*/
public function plus(iterable $items): Collection;
}
67 changes: 67 additions & 0 deletions src/Operation/Plus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Generator;
use loophp\collection\Collection;

/**
* @immutable
*
* @template TKey
* @template T
*/
final class Plus extends AbstractOperation
{
/**
* @template UKey
* @template U
*
* @return Closure(iterable<UKey, U>): Closure(iterable<TKey, T>): iterable<int|TKey|UKey, T|U>
*/
public function __invoke(): Closure
{
$comparatorCallback =
/**
* @param T $left
*
* @return Closure(T): bool
*/
static fn (mixed $left): Closure =>
/**
* @param T $right
*/
static fn (mixed $right): bool => $left === $right;

return
/**
* @param iterable<UKey, U> $items
*
* @return Closure(iterable<TKey, T>): iterable<int|TKey|UKey, T|U>
*/
static fn (iterable $items): Closure =>
/**
* @param iterable<TKey, T> $iterable
*
* @return Generator<int|TKey|UKey, T|U>
*/
static function (iterable $iterable) use ($items): Generator {
$collection = Collection::fromIterable($iterable)->squash();

foreach ($collection as $key => $value) {
yield $key => $value;
}

foreach ($items as $key => $value) {
if ($collection->keys()->contains($key)) {
continue;
}

yield $key => $value;
}
};
}
}
1 change: 1 addition & 0 deletions tests/unit/CollectionGenericOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ final class CollectionGenericOperationTest extends TestCase
* @dataProvider permutateOperationProvider
* @dataProvider pipeOperationProvider
* @dataProvider pluckOperationProvider
* @dataProvider plusOperationProvider
* @dataProvider prependOperationProvider
* @dataProvider productOperationProvider
* @dataProvider reductionOperationProvider
Expand Down
1 change: 1 addition & 0 deletions tests/unit/CustomCollectionGenericOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ final class CustomCollectionGenericOperationTest extends TestCase
* @dataProvider permutateOperationProvider
* @dataProvider pipeOperationProvider
* @dataProvider pluckOperationProvider
* @dataProvider plusOperationProvider
* @dataProvider prependOperationProvider
* @dataProvider productOperationProvider
* @dataProvider reductionOperationProvider
Expand Down
69 changes: 69 additions & 0 deletions tests/unit/Traits/GenericCollectionProviders.php
Original file line number Diff line number Diff line change
Expand Up @@ -3291,6 +3291,75 @@ public static function pluckOperationProvider()
];
}

public static function plusOperationProvider()
{
$output = static function (): Generator {
yield 0 => 'A';

yield 1 => 'B';

yield 2 => 'C';
};

yield [
'plus',
[range('A', 'C')],
[],
$output(),
];

$output = static function (): Generator {
yield 0 => 'A';

yield 1 => 'B';

yield 2 => 'C';
};

yield [
'plus',
[[]],
range('A', 'C'),
$output(),
];

$output = static function (): Generator {
yield 0 => 'A';

yield 1 => 'B';

yield 2 => 'E';

yield 3 => 'F';
};

yield [
'plus',
[range('C', 'F')],
range('A', 'B'),
$output(),
];

$input = static function (): Generator {
yield 'id' => 1;

yield 'id' => 2;
};

$output = static function (): Generator {
yield 'id' => 1;

yield 'id' => 2;
};

yield [
'plus',
[[]],
$input(),
$output(),
];
}

public static function prependOperationProvider()
{
$output = static function (): Generator {
Expand Down
Loading