Skip to content

Commit

Permalink
Add mapWithKey operation
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbalandan committed Nov 16, 2024
1 parent 7e8cb41 commit ee3e7da
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/Nexus/Collection/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,22 @@ public function mapKeys(\Closure $predicate): self
}, [$this]);
}

/**
* @template U
*
* @param (\Closure(T, TKey): U) $predicate
*
* @return self<TKey, U>
*/
public function mapWithKey(\Closure $predicate): self
{
return new self(static function (iterable $collection) use ($predicate): iterable {
foreach ($collection as $key => $item) {
yield $key => $predicate($item, $key);
}
}, [$this]);
}

/**
* @return self<int, T>
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Nexus/Collection/CollectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* @extends Operation\Keys<TKey, T>
* @extends Operation\Map<TKey, T>
* @extends Operation\MapKeys<TKey, T>
* @extends Operation\MapWithKey<TKey, T>
* @extends Operation\Values<TKey, T>
*/
interface CollectionInterface extends
Expand All @@ -37,6 +38,7 @@ interface CollectionInterface extends
Operation\Keys,
Operation\Map,
Operation\MapKeys,
Operation\MapWithKey,
Operation\Values
{
/**
Expand Down
41 changes: 41 additions & 0 deletions src/Nexus/Collection/Operation/MapWithKey.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Nexus framework.
*
* (c) John Paul E. Balandan, CPA <paulbalandan@gmail.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\Collection\Operation;

use Nexus\Collection\CollectionInterface;

/**
* @template TKey
* @template T
*/
interface MapWithKey
{
/**
* Returns a new collection consisting of items transformed by the
* mapping function `$predicate` that accepts the keys and values
* as inputs. The keys are left unchanged.
*
* ```
* Collection::wrap([1, 2, 3])->mapWithKey(static fn(int $v, int $k): int => $v + $k);
* => Collection([1, 3, 5])
* ```
*
* @template U
*
* @param (\Closure(T, TKey): U) $predicate
*
* @return CollectionInterface<TKey, U>
*/
public function mapWithKey(\Closure $predicate): CollectionInterface;
}
10 changes: 10 additions & 0 deletions tests/Collection/AbstractCollectionTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ public function testMapKeys(): void
);
}

public function testMapWithKey(): void
{
self::assertSame(
['a' => 1, 'aa' => 4, 'aaa' => 9],
$this->collection(['a' => 1, 'aa' => 2, 'aaa' => 3])
->mapWithKey(static fn(int $item, string $key): int => $item * \strlen($key))
->all(true),
);
}

public function testValues(): void
{
$collection = $this->collection(static function (): \Generator {
Expand Down
1 change: 1 addition & 0 deletions tests/Collection/data/collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@
assertType('Nexus\Collection\Collection<int, int>', Collection::wrap([10, 11])->map(static fn(int $item): int => $item ** 2));
assertType('Nexus\Collection\Collection<int, string>', Collection::wrap([1])->map(static fn(int $item): string => $item > 1 ? 'Yes' : 'No'));
assertType('Nexus\Collection\Collection<int<0, max>, int>', Collection::wrap(['apples' => 2])->mapKeys(static fn(string $key): int => \strlen($key)));
assertType('Nexus\Collection\Collection<int, int>', Collection::wrap([10])->mapWithKey(static fn(int $v, int $k): int => $v ** $k));

0 comments on commit ee3e7da

Please sign in to comment.