Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implements stable sorting #333

Merged
merged 1 commit into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2140,6 +2140,9 @@ Sort a collection using a callback. If no callback is provided, it will sort usi
By default, it will sort by values and using a callback. If you want to sort by keys, you can pass a parameter to change
the behaviour or use twice the flip operation. See the example below.

Since version 7.4, sorting is `stable` by default. Stable sort algorithms sort equal
elements in the same order that they appear in the input.

Interface: `Sortable`_

Signature: ``Collection::sort(int $type = Sortable::BY_VALUES, ?callable $callback = null): Collection;``
Expand Down
2 changes: 1 addition & 1 deletion src/Operation/Sort.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static function (iterable $iterable) use ($type, $callback): Generator {
* @param array{0:TKey|T, 1:T|TKey} $left
* @param array{0:TKey|T, 1:T|TKey} $right
*/
static fn (array $left, array $right): int => $callback($right[1], $left[1]);
static fn (array $left, array $right): int => (0 === $return = $callback($right[1], $left[1])) ? ($right[0] <=> $left[0]) : $return;

$sortedIterator =
/**
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/IssuesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,24 @@ public function testIssue264()
self::assertEquals('c', $subject->get(300));
self::assertEquals('d', $subject->get(400));
}

public function testIssue331(): void
{
$valueObjectFactory = static fn (int $id, int $weight) => new class($id, $weight) {
public function __construct(
public readonly int $id,
public readonly int $weight,
) {}
};

$input = Collection::fromIterable([
$valueObjectFactory(id: 1, weight: 1),
$valueObjectFactory(id: 2, weight: 1),
$valueObjectFactory(id: 3, weight: 1),
])
->sort(callback: static fn (object $a, object $b): int => $a->weight <=> $b->weight)
->map(static fn ($item): int => $item->id);

self::assertEquals([1, 2, 3], $input->all());
}
}
Loading