2 people like it.
Like the snippet!
Simple queue that allows for removing items anywhere as well as FIFO operation.
A simple queue that also allows for the removal of items waiting in the queue as well as FIFO operation. This is useful if for example you have a queue of items that might need to expire at different times if they have been waiting in the queue for too long.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
|
open System
open System.Collections.Generic
/// A simple queue that also allows for the removal of items waiting in the queue as well as FIFO operation.
type FilterableQueue<'a> () =
let queue = new LinkedList<'a>()
/// Add an item to the tail of the queue.
member x.Enqueue (item: 'a) = queue.AddLast item |> ignore
/// Get the item at the head of the queue and remove it, the result is None if the queue is empty.
member x.TryDequeue () =
match x.Count with
| 0 -> None
| _ -> let item = queue.First.Value
queue.RemoveFirst ()
Some item
/// The number of items currently in the queue.
member x.Count with get () = queue.Count
/// Remove items from the queue for which the predicate is true.
member x.RemoveSelectedItems predicate =
// A list that will contain any items removed from the queue.
let removedItems = new LinkedList<_>()
// Tail-recursive function to iterate over the nodes in the queue.
let rec loop (node: LinkedListNode<'a>) =
match predicate node.Value with
| true ->
// Predicate returned true, so remove the item from the queue and add it to the removedItems list.
let next = node.Next
removedItems.AddLast node.Value |> ignore
queue.Remove node
next
| false ->
// Item should not be removed if predicate returns false, just move onto the next element in the queue.
node.Next
|> function
// Either there is another node to process or not..
| null -> ()
| nextNode -> loop nextNode
// Start the scan of the nodes if there are any.
if queue.Count <> 0 then loop queue.First
// Evaluates to the list of items that were removed.
removedItems
// Example..
let q = FilterableQueue<int>()
q.Enqueue 3
q.Enqueue 7
q.Enqueue 9
// Filter anything where 8 is less then or equal to the item.
let removed = q.RemoveSelectedItems ((<=) 8)
let a = q.TryDequeue () // Some 3
let b = q.TryDequeue () // Some 7
let c = q.TryDequeue () // None
|
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type FilterableQueue<'a> =
new : unit -> FilterableQueue<'a>
member Enqueue : item:'a -> unit
member RemoveSelectedItems : predicate:('a -> bool) -> LinkedList<'a>
member TryDequeue : unit -> 'a option
member Count : int
Full name: Script.FilterableQueue<_>
A simple queue that also allows for the removal of items waiting in the queue as well as FIFO operation.
--------------------
new : unit -> FilterableQueue<'a>
val queue : LinkedList<'a>
Multiple items
type LinkedList<'T> =
new : unit -> LinkedList<'T> + 1 overload
member AddAfter : node:LinkedListNode<'T> * value:'T -> LinkedListNode<'T> + 1 overload
member AddBefore : node:LinkedListNode<'T> * value:'T -> LinkedListNode<'T> + 1 overload
member AddFirst : value:'T -> LinkedListNode<'T> + 1 overload
member AddLast : value:'T -> LinkedListNode<'T> + 1 overload
member Clear : unit -> unit
member Contains : value:'T -> bool
member CopyTo : array:'T[] * index:int -> unit
member Count : int
member Find : value:'T -> LinkedListNode<'T>
...
nested type Enumerator
Full name: System.Collections.Generic.LinkedList<_>
--------------------
LinkedList() : unit
LinkedList(collection: IEnumerable<'T>) : unit
val x : FilterableQueue<'a>
member FilterableQueue.Enqueue : item:'a -> unit
Full name: Script.FilterableQueue`1.Enqueue
Add an item to the tail of the queue.
val item : 'a
LinkedList.AddLast(node: LinkedListNode<'a>) : unit
LinkedList.AddLast(value: 'a) : LinkedListNode<'a>
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
member FilterableQueue.TryDequeue : unit -> 'a option
Full name: Script.FilterableQueue`1.TryDequeue
Get the item at the head of the queue and remove it, the result is None if the queue is empty.
property FilterableQueue.Count: int
The number of items currently in the queue.
union case Option.None: Option<'T>
property LinkedList.First: LinkedListNode<'a>
property LinkedListNode.Value: 'a
LinkedList.RemoveFirst() : unit
union case Option.Some: Value: 'T -> Option<'T>
member FilterableQueue.Count : int
Full name: Script.FilterableQueue`1.Count
The number of items currently in the queue.
property LinkedList.Count: int
member FilterableQueue.RemoveSelectedItems : predicate:('a -> bool) -> LinkedList<'a>
Full name: Script.FilterableQueue`1.RemoveSelectedItems
Remove items from the queue for which the predicate is true.
val predicate : ('a -> bool)
val removedItems : LinkedList<'a>
val loop : (LinkedListNode<'a> -> unit)
val node : LinkedListNode<'a>
Multiple items
type LinkedListNode<'T> =
new : value:'T -> LinkedListNode<'T>
member List : LinkedList<'T>
member Next : LinkedListNode<'T>
member Previous : LinkedListNode<'T>
member Value : 'T with get, set
Full name: System.Collections.Generic.LinkedListNode<_>
--------------------
LinkedListNode(value: 'T) : unit
val next : LinkedListNode<'a>
property LinkedListNode.Next: LinkedListNode<'a>
LinkedList.Remove(node: LinkedListNode<'a>) : unit
LinkedList.Remove(value: 'a) : bool
val nextNode : LinkedListNode<'a>
val q : FilterableQueue<int>
Full name: Script.q
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
member FilterableQueue.Enqueue : item:'a -> unit
Add an item to the tail of the queue.
val removed : LinkedList<int>
Full name: Script.removed
member FilterableQueue.RemoveSelectedItems : predicate:('a -> bool) -> LinkedList<'a>
Remove items from the queue for which the predicate is true.
val a : int option
Full name: Script.a
member FilterableQueue.TryDequeue : unit -> 'a option
Get the item at the head of the queue and remove it, the result is None if the queue is empty.
val b : int option
Full name: Script.b
val c : int option
Full name: Script.c
More information