Skip to content

Commit

Permalink
refactor: Update Associate operation.
Browse files Browse the repository at this point in the history
Add a $carry argument.

BREAKING CHANGE: yes
  • Loading branch information
drupol committed Sep 12, 2020
1 parent 6cb1e77 commit 168eb1a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 65 deletions.
4 changes: 2 additions & 2 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ public function it_can_associate(): void

$this::fromIterable($input)
->associate(
static function ($key, $value) {
static function ($carry, $key, $value) {
return $key * 2;
},
static function ($key, $value) {
static function ($carry, $key, $value) {
return $value * 2;
}
)
Expand Down
28 changes: 11 additions & 17 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,32 +244,26 @@ public function associate(
?callable $callbackForKeys = null,
?callable $callbackForValues = null
): CollectionInterface {
$callbackForKeys = $callbackForKeys ??
$defaultCallback =
/**
* @psalm-param TKey $key
* @psalm-param T $value
* @psalm-return TKey
* @param mixed $carry
* @psalm-param T|TKey $carry
*
* @param mixed $key
* @param mixed $value
*/
static function ($key, $value) {
return $key;
};

$callbackForValues = $callbackForValues ??
/**
* @psalm-param TKey $key
* @psalm-param T $value
* @psalm-return T
*
* @param mixed $key
* @param mixed $value
* @psalm-param T $value
*
* @psalm-return TKey|T
*/
static function ($key, $value) {
return $value;
static function ($carry, $key, $value) {
return $carry;
};

$callbackForKeys = $callbackForKeys ?? $defaultCallback;
$callbackForValues = $callbackForValues ?? $defaultCallback;

return $this->run(Associate::of()($callbackForKeys)($callbackForValues));
}

Expand Down
2 changes: 1 addition & 1 deletion src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
* @template-extends Combineable<TKey, T>
* @template-extends Compactable<TKey, T>
* @template-extends Containsable<T>
* @template-extends Currentable<TKey, T>
* @template-extends Cycleable<TKey, T>
* @template-extends Diffable<TKey, T>
* @template-extends Diffkeysable<TKey, T>
Expand Down Expand Up @@ -159,7 +160,6 @@
* @template-extends Tailable<TKey, T>
* @template-extends TakeWhileable<TKey, T>
* @template-extends Transposeable<TKey, T>
* @template-extends Unfoldable<TKey, T>
* @template-extends Unpackable<TKey, T>
* @template-extends Unpairable<TKey, T>
* @template-extends Untilable<TKey, T>
Expand Down
69 changes: 24 additions & 45 deletions src/Operation/Associate.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace loophp\collection\Operation;

use ArrayIterator;
use Closure;
use Generator;
use Iterator;
Expand All @@ -19,92 +20,70 @@
final class Associate extends AbstractOperation
{
/**
* @psalm-return Closure((callable(TKey, T):TKey)...): Closure((callable(TKey, T):T)...): Closure(Iterator<TKey, T>): Generator<TKey, T>
* @psalm-return Closure((callable(T, TKey, T, Iterator<TKey, T>): (T|TKey))...): Closure((callable(T, TKey, T, Iterator<TKey, T>): (T|TKey))...): Closure(Iterator<TKey, T>): Generator<TKey|T, T|TKey>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param callable(TKey, T):TKey ...$callbackForKeys
* @psalm-param callable(T, TKey, T, Iterator<TKey, T>): (T|TKey) ...$callbackForKeys
*
* @psalm-return Closure((callable(TKey, T):T)...): Closure(Iterator<TKey, T>): Generator<TKey, T>
* @psalm-return Closure((callable(T, TKey, T, Iterator<TKey, T>): (T|TKey))...): Closure(Iterator<TKey, T>): Generator<TKey|T, T|TKey>
*/
static function (callable ...$callbackForKeys): Closure {
return
/**
* @psalm-param callable(TKey, T):(T) ...$callbackForValues
* @psalm-param callable(T, TKey, T, Iterator<TKey, T>): (T|TKey) ...$callbackForValues
*
* @psalm-return Closure(Iterator<TKey, T>): Generator<TKey, T>
* @psalm-return Closure(Iterator<TKey, T>): Generator<TKey|T, T|TKey>
*/
static function (callable ...$callbackForValues) use ($callbackForKeys): Closure {
return
/**
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return Generator<TKey, T>
* @psalm-return Generator<TKey|T, T|TKey>
*/
static function (Iterator $iterator) use ($callbackForKeys, $callbackForValues): Generator {
$callbackForKeysFactory =
$callbackFactory =
/**
* @param mixed $key
* @psalm-param TKey $key
*
* @psalm-return Closure(T): Closure(TKey, callable(TKey, T): TKey): TKey
* @psalm-return Closure(T): Closure(T, callable(T, TKey, T, Iterator<TKey, T>): (T|TKey), int, Iterator<TKey, T>): (T|TKey)
*/
static function ($key): Closure {
return
/**
* @param mixed $value
* @psalm-param T $value
*
* @psalm-return Closure(TKey, callable(TKey, T): TKey): TKey
* @psalm-return Closure(T, callable(T, TKey, T, Iterator<TKey, T>): (T|TKey), int, Iterator<TKey, T>): (T|TKey)
*/
static function ($value) use ($key): Closure {
return
/**
* @param mixed $carry
* @psalm-param TKey $carry
* @psalm-param callable(TKey, T): TKey $callback
* @param mixed $initial
* @psalm-param T $initial
* @psalm-param callable(T, TKey, T, Iterator<TKey, T>): (T|TKey) $callback
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return TKey
* @psalm-return T|TKey
*/
static function ($carry, callable $callback) use ($key, $value) {
return $callback($carry, $value);
};
};
};

$callbackForValuesFactory =
/**
* @param mixed $key
* @psalm-param TKey $key
*
* @psalm-return Closure(T): Closure(T, callable(TKey, T): T): T
*/
static function ($key): Closure {
return
/**
* @param mixed $value
* @psalm-param T $value
*
* @psalm-return Closure(T, callable(TKey, T): T) :T
*/
static function ($value) use ($key): Closure {
return
/**
* @param mixed $carry
* @psalm-param T $carry
* @psalm-param callable(TKey, T): T $callback
* @psalm-return T
*/
static function ($carry, callable $callback) use ($key, $value) {
return $callback($key, $carry);
static function ($initial, callable $callback, int $callbackId, Iterator $iterator) use ($key, $value) {
return $callback($initial, $key, $value, $iterator);
};
};
};

foreach ($iterator as $key => $value) {
yield array_reduce($callbackForKeys, $callbackForKeysFactory($key)($value), $key) => array_reduce($callbackForValues, $callbackForValuesFactory($key)($value), $value);
/** @psalm-var Generator<int, TKey|T> $k */
$k = FoldLeft::of()($callbackFactory($key)($value))($key)(new ArrayIterator($callbackForKeys));

/** @psalm-var Generator<int, T|TKey> $c */
$c = FoldLeft::of()($callbackFactory($key)($value))($value)(new ArrayIterator($callbackForValues));

yield $k->current() => $c->current();
}
};
};
Expand Down

0 comments on commit 168eb1a

Please sign in to comment.