Skip to content

Commit

Permalink
Sort the results of PriorityQueue::toArray() according to priority
Browse files Browse the repository at this point in the history
Closes laminas#21

Signed-off-by: George Steel <[email protected]>
  • Loading branch information
gsteel committed Sep 14, 2023
1 parent e70f8e1 commit 19c9b80
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
23 changes: 16 additions & 7 deletions src/PriorityQueue.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use function serialize;
use function sprintf;
use function unserialize;
use function usort;

/**
* Re-usable, serializable priority queue implementation
Expand Down Expand Up @@ -245,13 +246,12 @@ public function __unserialize(array $data): void
}

/**
* Serialize to an array
* By default, returns only the item data, and in the order registered (not
* sorted). You may provide one of the EXTR_* flags as an argument, allowing
* Serialize to an array, ordered by priority
* By default, returns only the item data. You may provide one of the EXTR_* flags as an argument, allowing
* the ability to return priorities or both data and priority.
*
* @param self::EXTR_* $flag
* @return array<array-key, mixed>
* @return list<mixed>
* @psalm-return ($flag is self::EXTR_BOTH
* ? list<array{data: TValue, priority: int}>
* : $flag is self::EXTR_PRIORITY
Expand All @@ -261,10 +261,19 @@ public function __unserialize(array $data): void
*/
public function toArray(int $flag = self::EXTR_DATA): array
{
/**
* A manual sort is required because $item['priority'] as stored in the inner queue could be an array as
* opposed to an integer.
*/
$items = $this->items;
usort($items, function (array $a, array $b): int {
return $b['priority'] <=> $a['priority'];
});

return match ($flag) {
self::EXTR_BOTH => $this->items,
self::EXTR_PRIORITY => array_map(static fn($item): int => $item['priority'], $this->items),
default => array_map(static fn($item): mixed => $item['data'], $this->items),
self::EXTR_BOTH => $items,
self::EXTR_PRIORITY => array_map(static fn($item): int => $item['priority'], $items),
default => array_map(static fn($item): mixed => $item['data'], $items),
};
}

Expand Down
6 changes: 3 additions & 3 deletions test/PriorityQueueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public function testSerializationAndDeserializationShouldMaintainState(): void
public function testRetrievingQueueAsArrayReturnsDataOnlyByDefault(): void
{
$expected = [
'foo',
'bar',
'foo',
'baz',
'bat',
];
Expand All @@ -68,8 +68,8 @@ public function testRetrievingQueueAsArrayReturnsDataOnlyByDefault(): void
public function testCanCastToArrayOfPrioritiesOnly(): void
{
$expected = [
3,
4,
3,
2,
1,
];
Expand All @@ -80,8 +80,8 @@ public function testCanCastToArrayOfPrioritiesOnly(): void
public function testCanCastToArrayOfDataPriorityPairs(): void
{
$expected = [
['data' => 'foo', 'priority' => 3],
['data' => 'bar', 'priority' => 4],
['data' => 'foo', 'priority' => 3],
['data' => 'baz', 'priority' => 2],
['data' => 'bat', 'priority' => 1],
];
Expand Down

0 comments on commit 19c9b80

Please sign in to comment.