diff --git a/compiler/test/stdlib/queue.test.gr b/compiler/test/stdlib/queue.test.gr index c7fb80a367..a68ed53e9b 100644 --- a/compiler/test/stdlib/queue.test.gr +++ b/compiler/test/stdlib/queue.test.gr @@ -87,6 +87,45 @@ assert Queue.pop(queue) == Some(9) assert Queue.pop(queue) == Some(10) assert Queue.pop(queue) == None +// Queue.toArray +let queue1 = Queue.make() +assert Queue.toArray(queue1) == [>] +let queue2 = Queue.make() +Queue.push(1, queue2) +Queue.push(2, queue2) +Queue.push(3, queue2) +Queue.push(4, queue2) +Queue.pop(queue2) +Queue.pop(queue2) +Queue.push(5, queue2) +Queue.pop(queue2) +Queue.pop(queue2) +Queue.pop(queue2) +Queue.push(6, queue2) +Queue.push(7, queue2) +Queue.push(8, queue2) +Queue.push(9, queue2) +Queue.push(10, queue2) +Queue.push(11, queue2) +Queue.push(12, queue2) +Queue.push(13, queue2) +Queue.push(14, queue2) +Queue.push(15, queue2) +Queue.push(16, queue2) +Queue.push(17, queue2) +Queue.push(18, queue2) +Queue.push(19, queue2) +assert Queue.toArray(queue2) == + [> 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +let queue3 = Queue.make() +Queue.push(1, queue3) +Queue.push(2, queue3) +Queue.push(3, queue3) +assert Queue.toArray(queue3) == [> 1, 2, 3] +let queue4 = Queue.copy(queue3) +Queue.pop(queue4) +assert Queue.toArray(queue4) == [> 2, 3] + module Immutable { from Queue use { module Immutable as Queue } diff --git a/stdlib/queue.gr b/stdlib/queue.gr index 0cbafd171b..5be49943f7 100644 --- a/stdlib/queue.gr +++ b/stdlib/queue.gr @@ -164,6 +164,43 @@ provide let copy = queue => { { size, array: Array.copy(array), headIndex, tailIndex } } +/** + * Converts a queue into an array of its values. + * + * @param queue: The queue to convert + * @returns An array containing all values from the given queue + * + * @since v0.6.0 + */ +provide let toArray = queue => { + let arr = Array.make(queue.size, None) + let mut outIndex = 0 + if (queue.tailIndex < queue.headIndex) { + // Get the first half + for (let mut i = queue.headIndex; i < Array.length(queue.array); i += 1) { + arr[outIndex] = queue.array[i] + outIndex += 1 + } + // Get the second half + let endOffset = Array.length(queue.array) - queue.headIndex + for (let mut i = 0; i < queue.tailIndex; i += 1) { + arr[outIndex] = queue.array[i] + outIndex += 1 + } + } else { + for (let mut i = queue.headIndex; i < queue.tailIndex; i += 1) { + arr[outIndex] = queue.array[i] + outIndex += 1 + } + } + Array.map(e => { + match (e) { + Some(v) => v, + None => fail "Impossible: empty bucket in Queue.toArray", + } + }, arr) +} + /** * An immutable queue implementation. */ diff --git a/stdlib/queue.md b/stdlib/queue.md index 3f3ffc8c6d..3be61c5b26 100644 --- a/stdlib/queue.md +++ b/stdlib/queue.md @@ -244,6 +244,31 @@ Returns: |----|-----------| |`Queue`|A new queue containing the elements from the input| +### Queue.**toArray** + +
+Added in next +No other changes yet. +
+ +```grain +toArray : (queue: Queue
) => Array +``` + +Converts a queue into an array of its values. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`queue`|`Queue`|The queue to convert| + +Returns: + +|type|description| +|----|-----------| +|`Array`|An array containing all values from the given queue| + ## Queue.Immutable An immutable queue implementation.