Skip to content

Commit

Permalink
Update Associate operation.
Browse files Browse the repository at this point in the history
Let it use variadic parameters even though we don't use the feature in Collection.
  • Loading branch information
drupol committed Sep 3, 2020
1 parent 485c0fa commit 1b9ca3c
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 14 deletions.
8 changes: 8 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ public function associate(
?callable $callbackForKeys = null,
?callable $callbackForValues = null
): CollectionInterface {
$callbackForKeys = $callbackForKeys ?? static function ($key, $value) {
return $key;
};

$callbackForValues = $callbackForValues ?? static function ($key, $value) {
return $value;
};

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

Expand Down
86 changes: 72 additions & 14 deletions src/Operation/Associate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,99 @@
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*
* phpcs:disable Generic.Files.LineLength.TooLong
* phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact
*/
final class Associate extends AbstractOperation
{
/**
* @psalm-return Closure(null|callable(TKey, T):(TKey)): Closure(null|callable(TKey, T):(T)): Generator<TKey, T>
* @psalm-return Closure((callable(TKey, T):TKey)...): Closure((callable(TKey, T):T)...): Closure(Iterator<TKey, T>): Generator<TKey, T>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param null|callable(TKey, T):(TKey) $callbackForKeys
* @psalm-param callable(TKey, T):TKey ...$callbackForKeys
*
* @psalm-return Closure((callable(TKey, T):T)...): Closure(Iterator<TKey, T>): Generator<TKey, T>
*/
static function (?callable $callbackForKeys = null): Closure {
$callbackForKeys = $callbackForKeys ?? static function ($key, $value) {
return $key;
};

static function (callable ...$callbackForKeys): Closure {
return
/**
* @psalm-param null|callable(TKey, T):(T) $callbackForValues
* @psalm-param callable(TKey, T):(T) ...$callbackForValues
*
* @psalm-return Closure(Iterator<TKey, T>): Generator<TKey, T>
*/
static function (?callable $callbackForValues = null) use ($callbackForKeys): Closure {
$callbackForValues = $callbackForValues ?? static function ($key, $value) {
return $value;
};

static function (callable ...$callbackForValues) use ($callbackForKeys): Closure {
return
/**
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return Generator<TKey, T>
*/
static function (Iterator $iterator) use ($callbackForKeys, $callbackForValues): Generator {
$callbackForKeysFactory =
/**
* @param mixed $key
* @psalm-param TKey $key
*
* @psalm-return Closure(T): Closure(TKey, callable(TKey, T): TKey): TKey
*/
static function ($key): Closure {
return
/**
* @param mixed $value
* @psalm-param T $value
*
* @psalm-return Closure(TKey, callable(TKey, T): TKey): TKey
*/
static function ($value) use ($key): Closure {
return
/**
* @param mixed $carry
* @psalm-param TKey $carry
* @psalm-param callable(TKey, T): TKey $callback
*
* @psalm-return 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);
};
};
};

foreach ($iterator as $key => $value) {
yield $callbackForKeys($key, $value) => $callbackForValues($key, $value);
yield array_reduce($callbackForKeys, $callbackForKeysFactory($key)($value), $key) => array_reduce($callbackForValues, $callbackForValuesFactory($key)($value), $value);
}
};
};
Expand Down

0 comments on commit 1b9ca3c

Please sign in to comment.