mirror of
https://github.com/danog/endtoend-test-psl.git
synced 2024-11-30 04:39:48 +01:00
[Dict] add intersect and diff functions (#137)
This commit is contained in:
parent
781e8d5017
commit
2af0f628d3
42
src/Psl/Dict/diff.php
Normal file
42
src/Psl/Dict/diff.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Dict;
|
||||||
|
|
||||||
|
use Psl\Iter;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
use function array_diff;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the difference of iterables.
|
||||||
|
*
|
||||||
|
* @psalm-template Tk of array-key
|
||||||
|
* @psalm-template Tv
|
||||||
|
*
|
||||||
|
* @psalm-param iterable<Tk, Tv> $first
|
||||||
|
* @psalm-param iterable<Tk, Tv> $second
|
||||||
|
* @psalm-param iterable<Tk, Tv> ...$rest
|
||||||
|
*
|
||||||
|
* @psalm-return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
function diff(iterable $first, iterable $second, iterable ...$rest): array
|
||||||
|
{
|
||||||
|
if (Iter\is_empty($first)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_diff(from_iterable($first), from_iterable($second), ...Vec\map(
|
||||||
|
$rest,
|
||||||
|
/**
|
||||||
|
* @template Tk of array-key
|
||||||
|
* @template Tv
|
||||||
|
*
|
||||||
|
* @param iterable<Tk, Tv> $iterable
|
||||||
|
*
|
||||||
|
* @return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
static fn(iterable $iterable): array => from_iterable($iterable)
|
||||||
|
));
|
||||||
|
}
|
42
src/Psl/Dict/diff_by_key.php
Normal file
42
src/Psl/Dict/diff_by_key.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Dict;
|
||||||
|
|
||||||
|
use Psl\Iter;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
use function array_diff_key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the difference of iterables using keys for comparison.
|
||||||
|
*
|
||||||
|
* @psalm-template Tk of array-key
|
||||||
|
* @psalm-template Tv
|
||||||
|
*
|
||||||
|
* @psalm-param iterable<Tk, Tv> $first
|
||||||
|
* @psalm-param iterable<Tk, mixed> $second
|
||||||
|
* @psalm-param iterable<Tk, mixed> ...$rest
|
||||||
|
*
|
||||||
|
* @psalm-return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
function diff_by_key(iterable $first, iterable $second, iterable ...$rest): array
|
||||||
|
{
|
||||||
|
if (Iter\is_empty($first)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_diff_key(from_iterable($first), from_iterable($second), ...Vec\map(
|
||||||
|
$rest,
|
||||||
|
/**
|
||||||
|
* @template Tk of array-key
|
||||||
|
* @template Tv
|
||||||
|
*
|
||||||
|
* @param iterable<Tk, Tv> $iterable
|
||||||
|
*
|
||||||
|
* @return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
static fn(iterable $iterable): array => from_iterable($iterable)
|
||||||
|
));
|
||||||
|
}
|
42
src/Psl/Dict/intersect.php
Normal file
42
src/Psl/Dict/intersect.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Dict;
|
||||||
|
|
||||||
|
use Psl\Iter;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
use function array_intersect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the intersection of iterables.
|
||||||
|
*
|
||||||
|
* @template Tk of array-key
|
||||||
|
* @template Tv
|
||||||
|
*
|
||||||
|
* @param iterable<Tk, Tv> $first
|
||||||
|
* @param iterable<Tk, mixed> $second
|
||||||
|
* @param iterable<Tk, mixed> ...$rest
|
||||||
|
*
|
||||||
|
* @return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
function intersect(iterable $first, iterable $second, iterable ...$rest): array
|
||||||
|
{
|
||||||
|
if (Iter\is_empty($first)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_intersect(from_iterable($first), from_iterable($second), ...Vec\map(
|
||||||
|
$rest,
|
||||||
|
/**
|
||||||
|
* @template Tk of array-key
|
||||||
|
* @template Tv
|
||||||
|
*
|
||||||
|
* @param iterable<Tk, Tv> $iterable
|
||||||
|
*
|
||||||
|
* @return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
static fn(iterable $iterable): array => from_iterable($iterable)
|
||||||
|
));
|
||||||
|
}
|
42
src/Psl/Dict/intersect_by_key.php
Normal file
42
src/Psl/Dict/intersect_by_key.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Dict;
|
||||||
|
|
||||||
|
use Psl\Iter;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
use function array_intersect_key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the intersection of iterables using keys for comparison.
|
||||||
|
*
|
||||||
|
* @template Tk of array-key
|
||||||
|
* @template Tv
|
||||||
|
*
|
||||||
|
* @param iterable<Tk, Tv> $first
|
||||||
|
* @param iterable<Tk, mixed> $second
|
||||||
|
* @param iterable<Tk, mixed> ...$rest
|
||||||
|
*
|
||||||
|
* @return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
function intersect_by_key(iterable $first, iterable $second, iterable ...$rest): array
|
||||||
|
{
|
||||||
|
if (Iter\is_empty($first)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_intersect_key(from_iterable($first), from_iterable($second), ...Vec\map(
|
||||||
|
$rest,
|
||||||
|
/**
|
||||||
|
* @template Tk of array-key
|
||||||
|
* @template Tv
|
||||||
|
*
|
||||||
|
* @param iterable<Tk, Tv> $iterable
|
||||||
|
*
|
||||||
|
* @return array<Tk, Tv>
|
||||||
|
*/
|
||||||
|
static fn(iterable $iterable): array => from_iterable($iterable)
|
||||||
|
));
|
||||||
|
}
|
@ -129,6 +129,10 @@ final class Loader
|
|||||||
'Psl\Dict\take_while',
|
'Psl\Dict\take_while',
|
||||||
'Psl\Dict\unique',
|
'Psl\Dict\unique',
|
||||||
'Psl\Dict\unique_by',
|
'Psl\Dict\unique_by',
|
||||||
|
'Psl\Dict\diff',
|
||||||
|
'Psl\Dict\diff_by_key',
|
||||||
|
'Psl\Dict\intersect',
|
||||||
|
'Psl\Dict\intersect_by_key',
|
||||||
'Psl\Fun\after',
|
'Psl\Fun\after',
|
||||||
'Psl\Fun\identity',
|
'Psl\Fun\identity',
|
||||||
'Psl\Fun\pipe',
|
'Psl\Fun\pipe',
|
||||||
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace Psl\Iter;
|
namespace Psl\Iter;
|
||||||
|
|
||||||
use Generator;
|
use Generator;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chains the iterables that were passed as arguments.
|
* Chains the iterables that were passed as arguments.
|
||||||
@ -23,6 +24,10 @@ use Generator;
|
|||||||
* @psalm-param iterable<Tk, Tv> ...$iterables Iterables to chain
|
* @psalm-param iterable<Tk, Tv> ...$iterables Iterables to chain
|
||||||
*
|
*
|
||||||
* @psalm-return Iterator<Tk, Tv>
|
* @psalm-return Iterator<Tk, Tv>
|
||||||
|
*
|
||||||
|
* @deprecated use `Vec\concat` instead.
|
||||||
|
*
|
||||||
|
* @see Vec\concat()
|
||||||
*/
|
*/
|
||||||
function chain(iterable ...$iterables): Iterator
|
function chain(iterable ...$iterables): Iterator
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace Psl\Iter;
|
namespace Psl\Iter;
|
||||||
|
|
||||||
use Generator;
|
use Generator;
|
||||||
|
use Psl\Dict;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @psalm-template Tk
|
* @psalm-template Tk
|
||||||
@ -15,6 +16,10 @@ use Generator;
|
|||||||
* @psalm-param iterable<Tk, mixed> ...$rest
|
* @psalm-param iterable<Tk, mixed> ...$rest
|
||||||
*
|
*
|
||||||
* @psalm-return Iterator<Tk, Tv>
|
* @psalm-return Iterator<Tk, Tv>
|
||||||
|
*
|
||||||
|
* @deprecated use `Dict\diff_by_key` instead.
|
||||||
|
*
|
||||||
|
* @see Dict\diff_by_key()
|
||||||
*/
|
*/
|
||||||
function diff_by_key(iterable $first, iterable $second, iterable ...$rest): Iterator
|
function diff_by_key(iterable $first, iterable $second, iterable ...$rest): Iterator
|
||||||
{
|
{
|
||||||
|
34
tests/Psl/Dict/DiffByKeyTest.php
Normal file
34
tests/Psl/Dict/DiffByKeyTest.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Tests\Dict;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psl\Dict;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
final class DiffByKeyTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider provideData
|
||||||
|
*/
|
||||||
|
public function testDiffByKey(array $expected, iterable $first, iterable $second, iterable ...$rest): void
|
||||||
|
{
|
||||||
|
static::assertSame($expected, Dict\diff_by_key($first, $second, ...$rest));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideData(): iterable
|
||||||
|
{
|
||||||
|
yield [[], [], [], []];
|
||||||
|
yield [[], [], [1, 2, 3]];
|
||||||
|
yield [[], [], [1, 2, 3], []];
|
||||||
|
yield [[], [], [1, 2, 3], [], [4, 5]];
|
||||||
|
|
||||||
|
yield [[1, 2], [1, 2], [], []];
|
||||||
|
yield [[1, 2], [1, 2], ['foo' => 2], []];
|
||||||
|
yield [[1, 2], [1, 2], [], ['baz' => 1]];
|
||||||
|
yield [[6 => 7, 7 => 8], Vec\range(1, 8), Vec\range(1, 6), []];
|
||||||
|
yield [[7 => 8], Vec\range(1, 8), Vec\range(1, 6), [6 => 7]];
|
||||||
|
}
|
||||||
|
}
|
36
tests/Psl/Dict/DiffTest.php
Normal file
36
tests/Psl/Dict/DiffTest.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Tests\Dict;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psl\Dict;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
final class DiffTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider provideData
|
||||||
|
*/
|
||||||
|
public function testDiff(array $expected, iterable $first, iterable $second, iterable ...$rest): void
|
||||||
|
{
|
||||||
|
static::assertSame($expected, Dict\diff($first, $second, ...$rest));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideData(): iterable
|
||||||
|
{
|
||||||
|
yield [[], [], [], []];
|
||||||
|
yield [[], [], [1, 2, 3]];
|
||||||
|
yield [[], [], [1, 2, 3], []];
|
||||||
|
yield [[], [], [1, 2, 3], [], [4, 5]];
|
||||||
|
|
||||||
|
yield [[1, 2], [1, 2], [], []];
|
||||||
|
yield [[1], [1, 2], ['foo' => 2], []];
|
||||||
|
yield [[1 => 2], [1, 2], [], ['baz' => 1]];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], ['baz' => 1]];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], ['baz' => 1]];
|
||||||
|
yield [[6 => 7, 7 => 8], Vec\range(1, 8), Vec\range(1, 6), []];
|
||||||
|
yield [[7 => 8], Vec\range(1, 8), Vec\range(1, 6), [6 => 7]];
|
||||||
|
}
|
||||||
|
}
|
38
tests/Psl/Dict/IntersectByKeyTest.php
Normal file
38
tests/Psl/Dict/IntersectByKeyTest.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Tests\Dict;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psl\Dict;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
final class IntersectByKeyTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider provideData
|
||||||
|
*/
|
||||||
|
public function testIntersectByKey(array $expected, iterable $first, iterable $second, iterable ...$rest): void
|
||||||
|
{
|
||||||
|
static::assertSame($expected, Dict\intersect_by_key($first, $second, ...$rest));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideData(): iterable
|
||||||
|
{
|
||||||
|
yield [[], [], [], []];
|
||||||
|
yield [[], [], [1, 2, 3]];
|
||||||
|
yield [[], [], [1, 2, 3], []];
|
||||||
|
yield [[], [], [1, 2, 3], [], [4, 5]];
|
||||||
|
|
||||||
|
yield [[], [1, 2], [], []];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], []];
|
||||||
|
yield [[], [1, 2], [], ['baz' => 1]];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], ['baz' => 1]];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], ['baz' => 1]];
|
||||||
|
yield [[], [1, 2], ['foo' => 2, 'baz' => 1]];
|
||||||
|
yield [[1, 2, 3, 4, 5, 6], Vec\range(1, 8), Vec\range(1, 6)];
|
||||||
|
yield [[], Vec\range(1, 8), Vec\range(1, 6), []];
|
||||||
|
yield [[5 => 6], Vec\range(1, 8), Vec\range(1, 6), [5 => 6, 6 => 7]];
|
||||||
|
}
|
||||||
|
}
|
38
tests/Psl/Dict/IntersectTest.php
Normal file
38
tests/Psl/Dict/IntersectTest.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Psl\Tests\Dict;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psl\Dict;
|
||||||
|
use Psl\Vec;
|
||||||
|
|
||||||
|
final class IntersectTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider provideData
|
||||||
|
*/
|
||||||
|
public function testIntersect(array $expected, iterable $first, iterable $second, iterable ...$rest): void
|
||||||
|
{
|
||||||
|
static::assertSame($expected, Dict\intersect($first, $second, ...$rest));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideData(): iterable
|
||||||
|
{
|
||||||
|
yield [[], [], [], []];
|
||||||
|
yield [[], [], [1, 2, 3]];
|
||||||
|
yield [[], [], [1, 2, 3], []];
|
||||||
|
yield [[], [], [1, 2, 3], [], [4, 5]];
|
||||||
|
|
||||||
|
yield [[], [1, 2], [], []];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], []];
|
||||||
|
yield [[], [1, 2], [], ['baz' => 1]];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], ['baz' => 1]];
|
||||||
|
yield [[], [1, 2], ['foo' => 2], ['baz' => 1]];
|
||||||
|
yield [[1, 2], [1, 2], ['foo' => 2, 'baz' => 1]];
|
||||||
|
yield [[1, 2, 3, 4, 5, 6], Vec\range(1, 8), Vec\range(1, 6)];
|
||||||
|
yield [[], Vec\range(1, 8), Vec\range(1, 6), []];
|
||||||
|
yield [[5 => 6], Vec\range(1, 8), Vec\range(1, 6), [5 => 6, 6 => 7]];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user