Skip to content

Commit

Permalink
Merge pull request #74 from MortalFlesh/feature/add-partition
Browse files Browse the repository at this point in the history
Add IList::partition method
  • Loading branch information
MortalFlesh authored Nov 28, 2023
2 parents 1037c97 + 4907002 commit a64f28f
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<!-- There is always Unreleased section on the top. Subsections (Add, Changed, Fix, Removed) should be Add as needed. -->
## Unreleased
- Add `Immutable/Generic/IList::partition` method

## 7.1.1- 2023-11-25
- Fix return type of `sortBy` and `sortByDescending` methods
Expand Down
9 changes: 9 additions & 0 deletions src/Immutable/Generic/IList.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,15 @@ public function max(): mixed;
*/
public function maxBy(callable $callback): mixed;

/**
* Splits the collection into two collections, containing the elements for which the given predicate returns True and False respectively.
* Element order is preserved in both of the created lists.
*
* @phpstan-param callable(TValue, TIndex=): bool $predicate
* @phpstan-return array{0:IList<TValue>, 1: IList<TValue>}
*/
public function partition(callable $predicate): array;

/** @phpstan-return \MF\Collection\Mutable\Generic\IList<TValue> */
public function asMutable(): \MF\Collection\Mutable\Generic\IList;

Expand Down
24 changes: 24 additions & 0 deletions src/Immutable/Generic/ListCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,30 @@ public function maxBy(callable $callback): mixed
return $max;
}

/**
* Splits the collection into two collections, containing the elements for which the given predicate returns True and False respectively.
* Element order is preserved in both of the created lists.
*
* @phpstan-param callable(TValue, TIndex=): bool $predicate
* @phpstan-return array{0:IList<TValue>, 1: IList<TValue>}
*/
public function partition(callable $predicate): array
{
$predicate = Callback::curry($predicate);

$trueList = [];
$falseList = [];
foreach ($this as $i => $v) {
if ($predicate($v, $i)) {
$trueList[] = $v;
} else {
$falseList[] = $v;
}
}

return [new static($trueList), new static($falseList)];
}

/** @phpstan-return \MF\Collection\Mutable\Generic\IList<TValue> */
public function asMutable(): \MF\Collection\Mutable\Generic\IList
{
Expand Down
5 changes: 5 additions & 0 deletions tests/Fixtures/SimpleEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

class SimpleEntity implements EntityInterface
{
public static function create(int $id): self
{
return new self($id);
}

public function __construct(private int $id)
{
}
Expand Down
44 changes: 44 additions & 0 deletions tests/Immutable/Generic/ListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -847,4 +847,48 @@ public function testShouldMapListAndUseIndexInMapping(): void

$this->assertSame([0, 2, 6, 12, 20], $list->toArray());
}

/** @dataProvider provideListForPartition */
public function testShouldPartitionList(IList $list, callable $predicate, array $expected): void
{
$actual = $list->partition($predicate);

$this->assertEquals($expected, $actual);
}

public static function provideListForPartition(): array
{
return [
// list, predicate, expected
'empty' => [
new ListCollection(),
fn (int $i) => $i % 2 === 0,
[new ListCollection(), new ListCollection()],
],
'even/odd' => [
Seq::range('0..10')->toList(),
fn (int $i) => $i % 2 === 0,
[
ListCollection::from([0, 2, 4, 6, 8, 10]),
ListCollection::from([1, 3, 5, 7, 9]),
],
],
'even/odd (no odds)' => [
Seq::range('0..10')->toList()->filter(fn (int $i) => $i % 2 === 0),
fn (int $i) => $i % 2 === 0,
[
ListCollection::from([0, 2, 4, 6, 8, 10]),
ListCollection::from([]),
],
],
'objects' => [
Seq::range('0..10')->toList()->map(SimpleEntity::create(...)),
fn (SimpleEntity $entity) => $entity->getId() > 5,
[
Seq::range('6..10')->toList()->map(SimpleEntity::create(...)),
Seq::range('0..5')->toList()->map(SimpleEntity::create(...)),
],
],
];
}
}

0 comments on commit a64f28f

Please sign in to comment.