mirror of
https://github.com/danog/endtoend-test-psl.git
synced 2025-01-22 05:11:47 +01:00
[Arr] add pure implementations of Iter\filter{_keys, nulls, _with_key}
This commit is contained in:
parent
795d8793ac
commit
95e0cb37ad
45
src/Psl/Arr/filter.php
Normal file
45
src/Psl/Arr/filter.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Arr;
|
||||
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* Returns an array containing only the values for which the given predicate
|
||||
* returns `true`.
|
||||
*
|
||||
* The default predicate is casting the value to boolean.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Arr\filter(['', '0', 'a', 'b'])
|
||||
* => Arr('a', 'b')
|
||||
*
|
||||
* Arr\filter(['foo', 'bar', 'baz', 'qux'], fn(string $value): bool => Str\contains($value, 'a'));
|
||||
* => Arr('bar', 'baz')
|
||||
*
|
||||
* @psalm-template Tk of array-key
|
||||
* @psalm-template Tv
|
||||
*
|
||||
* @psalm-param array<Tk, Tv> $array
|
||||
* @psalm-param (pure-callable(Tv): bool)|null $predicate
|
||||
*
|
||||
* @psalm-return array<Tk, Tv>
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function filter(array $array, ?callable $predicate = null): array
|
||||
{
|
||||
/** @psalm-var (pure-callable(Tv): bool) $predicate */
|
||||
$predicate = $predicate ?? Closure::fromCallable('Psl\Internal\boolean');
|
||||
$result = [];
|
||||
foreach ($array as $k => $v) {
|
||||
if ($predicate($v)) {
|
||||
$result[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
45
src/Psl/Arr/filter_keys.php
Normal file
45
src/Psl/Arr/filter_keys.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Arr;
|
||||
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* Returns an array containing only the keys for which the given predicate
|
||||
* returns `true`.
|
||||
*
|
||||
* The default predicate is casting the key to boolean.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Arr\filter_keys([0 => 'a', 1 => 'b'])
|
||||
* => Arr(1 => 'b')
|
||||
*
|
||||
* Arr\filter_keys([0 => 'a', 1 => 'b', 2 => 'c'], fn(int $key): bool => $key <= 1);
|
||||
* => Arr(0 => 'a', 1 => 'b')
|
||||
*
|
||||
* @psalm-template Tk of array-key
|
||||
* @psalm-template Tv
|
||||
*
|
||||
* @psalm-param array<Tk, Tv> $array
|
||||
* @psalm-param (pure-callable(Tk): bool)|null $predicate
|
||||
*
|
||||
* @psalm-return array<Tk, Tv>
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function filter_keys(array $array, ?callable $predicate = null): array
|
||||
{
|
||||
/** @psalm-var (pure-callable(Tk): bool) $predicate */
|
||||
$predicate = $predicate ?? Closure::fromCallable('Psl\Internal\boolean');
|
||||
$result = [];
|
||||
foreach ($array as $k => $v) {
|
||||
if ($predicate($k)) {
|
||||
$result[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
33
src/Psl/Arr/filter_nulls.php
Normal file
33
src/Psl/Arr/filter_nulls.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Arr;
|
||||
|
||||
/**
|
||||
* Filter out null values from the given array.
|
||||
*
|
||||
* Example:
|
||||
* Arr\filter_nulls([1, null, 5])
|
||||
* => Arr(1, 5)
|
||||
*
|
||||
* @psalm-template T
|
||||
*
|
||||
* @psalm-param list<T|null> $array
|
||||
*
|
||||
* @psalm-return list<T>
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function filter_nulls(array $array): array
|
||||
{
|
||||
/** @psalm-var list<T> $result */
|
||||
$result = [];
|
||||
foreach ($array as $value) {
|
||||
if (null !== $value) {
|
||||
$result[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
56
src/Psl/Arr/filter_with_key.php
Normal file
56
src/Psl/Arr/filter_with_key.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Arr;
|
||||
|
||||
use Psl;
|
||||
|
||||
/**
|
||||
* Returns an array containing only the keys and values for which the given predicate
|
||||
* returns `true`.
|
||||
*
|
||||
* The default predicate is casting both they key and the value to boolean.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Arr\filter_with_key(['a', '0', 'b', 'c'])
|
||||
* => Iter('b', 'c')
|
||||
*
|
||||
* Arr\filter_with_key(
|
||||
* ['foo', 'bar', 'baz', 'qux'],
|
||||
* fn(int $key, string $value): bool => $key > 1 && Str\contains($value, 'a')
|
||||
* );
|
||||
* => Arr('baz')
|
||||
*
|
||||
* @psalm-template Tk of array-key
|
||||
* @psalm-template Tv
|
||||
*
|
||||
* @psalm-param array<Tk, Tv> $array
|
||||
* @psalm-param (pure-callable(Tk, Tv): bool)|null $predicate
|
||||
*
|
||||
* @psalm-return array<Tk, Tv>
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function filter_with_key(array $array, ?callable $predicate = null): array
|
||||
{
|
||||
$predicate = $predicate ??
|
||||
/**
|
||||
* @psalm-param Tk $k
|
||||
* @psalm-param Tv $v
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
fn ($k, $v): bool => Psl\Internal\boolean($v);
|
||||
|
||||
/** @psalm-var array<Tk, Tv> $result */
|
||||
$result = [];
|
||||
foreach ($array as $k => $v) {
|
||||
if ($predicate($k, $v)) {
|
||||
$result[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
@ -86,6 +86,10 @@ final class Loader
|
||||
'Psl\Arr\slice',
|
||||
'Psl\Arr\take',
|
||||
'Psl\Arr\take_while',
|
||||
'Psl\Arr\filter',
|
||||
'Psl\Arr\filter_keys',
|
||||
'Psl\Arr\filter_nulls',
|
||||
'Psl\Arr\filter_with_key',
|
||||
'Psl\Asio\wrap',
|
||||
'Psl\Internal\boolean',
|
||||
'Psl\Internal\type',
|
||||
|
30
tests/Psl/Arr/FilterKeysTest.php
Normal file
30
tests/Psl/Arr/FilterKeysTest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Arr;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Arr;
|
||||
|
||||
class FilterKeysTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testFilterKeys(array $expected, array $array, ?callable $predicate = null): void
|
||||
{
|
||||
$result = Arr\filter_keys($array, $predicate);
|
||||
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[], []];
|
||||
yield [[1 => 'b'], ['a', 'b']];
|
||||
yield [[], ['a', 'b'], fn () => false];
|
||||
yield [['a', 'b'], ['a', 'b'], fn (int $_): bool => true];
|
||||
yield [['a'], ['a', 'b'], fn (int $k): bool => 1 !== $k];
|
||||
}
|
||||
}
|
20
tests/Psl/Arr/FilterNullsTest.php
Normal file
20
tests/Psl/Arr/FilterNullsTest.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Arr;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Arr;
|
||||
|
||||
class FilterNullsTest extends TestCase
|
||||
{
|
||||
public function testFilterNulls(): void
|
||||
{
|
||||
self::assertCount(0, Arr\filter_nulls([]));
|
||||
self::assertCount(0, Arr\filter_nulls([null, null]));
|
||||
self::assertCount(1, Arr\filter_nulls([null, false]));
|
||||
self::assertCount(1, Arr\filter_nulls([null, 'null']));
|
||||
self::assertCount(1, Arr\filter_nulls(['null']));
|
||||
}
|
||||
}
|
30
tests/Psl/Arr/FilterTest.php
Normal file
30
tests/Psl/Arr/FilterTest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Arr;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Arr;
|
||||
|
||||
class FilterTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testFilter(array $expected, array $array, ?callable $predicate = null): void
|
||||
{
|
||||
$result = Arr\filter($array, $predicate);
|
||||
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[], []];
|
||||
yield [['a', 'b'], ['a', 'b']];
|
||||
yield [[], ['a', 'b'], fn () => false];
|
||||
yield [['a', 'b'], ['a', 'b'], fn (string $_): bool => true];
|
||||
yield [['a'], ['a', 'b'], fn (string $v): bool => 'b' !== $v];
|
||||
}
|
||||
}
|
34
tests/Psl/Arr/FilterWithKeyTest.php
Normal file
34
tests/Psl/Arr/FilterWithKeyTest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Arr;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Arr;
|
||||
|
||||
class FilterWithKeyTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testFilterWithKey(array $expected, array $array, ?callable $predicate = null): void
|
||||
{
|
||||
$result = Arr\filter_with_key($array, $predicate);
|
||||
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[], []];
|
||||
yield [['a', 'b'], ['a', 'b']];
|
||||
yield [[], ['a', 'b'], fn (int $_k, string $_v) => false];
|
||||
yield [['a', 'b'], ['a', 'b'], fn (int $_k, string $_v): bool => true];
|
||||
yield [['a'], ['a', 'b'], fn (int $k, string $v): bool => 'b' !== $v];
|
||||
yield [[], ['a', 'b'], fn (int $k, string $v): bool => 'b' !== $v && 0 !== $k];
|
||||
yield [['a'], ['a', 'b'], fn (int $k, string $v): bool => 'b' !== $v && 1 !== $k];
|
||||
yield [[], ['a', 'b'], fn (int $k, string $v): bool => 'a' !== $v && 1 !== $k];
|
||||
yield [[1 => 'b'], ['a', 'b'], fn (int $k, string $v): bool => 'a' !== $v && 0 !== $k];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user