Skip to content

Commit

Permalink
Merge pull request #109 from gsteel/priority-queue-to-array-ordered
Browse files Browse the repository at this point in the history
Sort the results of PriorityQueue::toArray() according to priority
  • Loading branch information
gsteel authored Sep 18, 2023
2 parents e70f8e1 + e32a318 commit 6a40cee
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
4 changes: 4 additions & 0 deletions docs/book/v4/migration/v3-to-v4.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ All classes have been updated to make use of parameter and return types. In gene

The addition of property, parameter and return types will cause fatal errors for extending classes that re-define those properties or override changed methods. If you have extended from any classes in laminas-stdlib, you should check that property types and method signatures are compatible and update them if they are not aligned.

### `PriorityQueue::toArray()` Now Returns Data in Order of Priority

In previous versions, `PriorityQueue::toArray()` returned data in insertion order. This method now returns data in priority order making it effectively the same as `iterator_to_array($queue)`, with the exception that you can pass extraction flags to `PriorityQueue::toArray()`.

## Removed Features

None.
Expand Down
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 6a40cee

Please sign in to comment.