From 19c9b8098cd3db1ff98efaa141e9baf959792c20 Mon Sep 17 00:00:00 2001 From: George Steel Date: Thu, 14 Sep 2023 22:34:33 +0100 Subject: [PATCH] Sort the results of PriorityQueue::toArray() according to priority Closes #21 Signed-off-by: George Steel --- src/PriorityQueue.php | 23 ++++++++++++++++------- test/PriorityQueueTest.php | 6 +++--- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/PriorityQueue.php b/src/PriorityQueue.php index 3b19136d..8cd49a0b 100644 --- a/src/PriorityQueue.php +++ b/src/PriorityQueue.php @@ -17,6 +17,7 @@ use function serialize; use function sprintf; use function unserialize; +use function usort; /** * Re-usable, serializable priority queue implementation @@ -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 + * @return list * @psalm-return ($flag is self::EXTR_BOTH * ? list * : $flag is self::EXTR_PRIORITY @@ -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), }; } diff --git a/test/PriorityQueueTest.php b/test/PriorityQueueTest.php index b7871d11..49c14013 100644 --- a/test/PriorityQueueTest.php +++ b/test/PriorityQueueTest.php @@ -56,8 +56,8 @@ public function testSerializationAndDeserializationShouldMaintainState(): void public function testRetrievingQueueAsArrayReturnsDataOnlyByDefault(): void { $expected = [ - 'foo', 'bar', + 'foo', 'baz', 'bat', ]; @@ -68,8 +68,8 @@ public function testRetrievingQueueAsArrayReturnsDataOnlyByDefault(): void public function testCanCastToArrayOfPrioritiesOnly(): void { $expected = [ - 3, 4, + 3, 2, 1, ]; @@ -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], ];