[Arr] add pure implementations of Iter\map{keys,with_key}

This commit is contained in:
azjezz 2020-09-02 23:06:20 +01:00
parent 88f3d7edc0
commit 6c80307585
7 changed files with 207 additions and 0 deletions

39
src/Psl/Arr/map.php Normal file
View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Psl\Arr;
/**
* Applies a mapping function to all values of an array.
*
* The function is passed the current array value and should return a
* modified array value.
*
* The key is left as-is and not passed to the mapping function.
*
* Examples:
*
* Arr\map([1, 2, 3, 4, 5], fn($i) => $i * 2);
* => Arr(2, 4, 6, 8, 10)
*
* @psalm-template Tk of array-key
* @psalm-template Tv
* @psalm-template T
*
* @psalm-param array<Tk, Tv> $array Array to be mapped over
* @psalm-param (pure-callable(Tv): T) $function
*
* @psalm-return array<Tk, T>
*
* @psalm-pure
*/
function map(array $array, callable $function): array
{
$result = [];
foreach ($array as $key => $value) {
$result[$key] = $function($value);
}
return $result;
}

39
src/Psl/Arr/map_keys.php Normal file
View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Psl\Arr;
/**
* Applies a mapping function to all keys of an array.
*
* The function is passed the current array key and should return a
* modified array key.
*
* The value is left as-is and not passed to the mapping function.
*
* Examples:
*
* Arr\map_keys([0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5], fn($i) => $i * 2);
* => Arr(0 => 1, 2 => 2, 4 => 3, 6 => 4, 8 => 5)
*
* @psalm-template Tk1 of array-key
* @psalm-template Tk2 of array-key
* @psalm-template Tv
*
* @psalm-param array<Tk1, Tv> $array Array to be mapped over
* @psalm-param (pure-callable(Tk1): Tk2) $function
*
* @psalm-return array<Tk2, Tv>
*
* @psalm-pure
*/
function map_keys(array $array, callable $function): array
{
$result = [];
foreach ($array as $key => $value) {
$result[$function($key)] = $value;
}
return $result;
}

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Psl\Arr;
/**
* Applies a mapping function to all values of an array.
*
* The function is passed the current array key and value and should return a
* modified array value.
*
* The key is left as-is.
*
* Examples:
*
* Arr\map_with_key([1, 2, 3, 4, 5], fn($k, $v) => $k + $v);
* => Arr(1, 3, 5, 7, 9)
*
* @psalm-template Tk of array-key
* @psalm-template Tv
* @psalm-template T
*
* @psalm-param array<Tk, Tv> $array Array to be mapped over
* @psalm-param (pure-callable(Tk,Tv): T) $function
*
* @psalm-return array<Tk, T>
*
* @psalm-pure
*/
function map_with_key(array $array, callable $function): array
{
$result = [];
foreach ($array as $key => $value) {
$result[$key] = $function($key, $value);
}
return $result;
}

View File

@ -90,6 +90,9 @@ final class Loader
'Psl\Arr\filter_keys',
'Psl\Arr\filter_nulls',
'Psl\Arr\filter_with_key',
'Psl\Arr\map',
'Psl\Arr\map_keys',
'Psl\Arr\map_with_key',
'Psl\Asio\wrap',
'Psl\Internal\boolean',
'Psl\Internal\type',

View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Arr;
use PHPUnit\Framework\TestCase;
use Psl\Arr;
class MapKeysTest extends TestCase
{
/**
* @dataProvider provideData
*/
public function testMapKeys(array $expected, array $array, callable $function): void
{
$result = Arr\map_keys($array, $function);
self::assertSame($expected, $result);
}
public function provideData(): iterable
{
yield [[1, 2, 3], [1, 2, 3], fn (int $k): int => $k];
yield [[1, 2 => 2, 4 => 3], [1, 2, 3], fn (int $k): int => $k * 2];
yield [['0' => 1, '1' => 2, '2' => 3], [1, 2, 3], fn (int $k): string => (string) $k];
yield [[], [], fn (int $k): string => (string) $k];
}
}

29
tests/Psl/Arr/MapTest.php Normal file
View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Arr;
use PHPUnit\Framework\TestCase;
use Psl\Arr;
class MapTest extends TestCase
{
/**
* @dataProvider provideData
*/
public function testMap(array $expected, array $array, callable $function): void
{
$result = Arr\map($array, $function);
self::assertSame($expected, $result);
}
public function provideData(): iterable
{
yield [[1, 2, 3], [1, 2, 3], fn (int $v): int => $v];
yield [[2, 4, 6], [1, 2, 3], fn (int $v): int => $v * 2];
yield [['1', '2', '3'], [1, 2, 3], fn (int $v): string => (string)$v];
yield [[], [], fn (int $k): string => (string)$v];
}
}

View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Arr;
use PHPUnit\Framework\TestCase;
use Psl\Arr;
class MapWithKeyTest extends TestCase
{
/**
* @dataProvider provideData
*/
public function testMapWithKey(array $expected, array $array, callable $function): void
{
$result = Arr\map_with_key($array, $function);
self::assertSame($expected, $result);
}
public function provideData(): iterable
{
yield [[1, 3, 5], [1, 2, 3], fn (int $k, int $v): int => $k + $v];
yield [[0, 4, 16], [1, 2, 3], fn (int $k, int $v): int => $k * (2 ** $v)];
yield [['1', '3', '5'], [1, 2, 3], fn (int $k, int $v): string => (string) ($k + $v)];
yield [[], [], fn (int $k, int $v): string => (string) ($k + $v)];
}
}