| 76 | } |
| 77 | |
| 78 | class TrieIterator<in out V, out T> implements IterableIterator<T> { |
| 79 | stack: Array<[Node<V>, string, boolean]> = [] |
| 80 | |
| 81 | constructor( |
| 82 | readonly trie: TrieImpl<V>, |
| 83 | readonly f: TraversalMap<string, V, T>, |
| 84 | readonly filter: TraversalFilter<string, V> |
| 85 | ) { |
| 86 | const root = trie._root !== undefined ? trie._root : undefined |
| 87 | if (root !== undefined) { |
| 88 | this.stack.push([root, "", false]) |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | next(): IteratorResult<T> { |
| 93 | while (this.stack.length > 0) { |
| 94 | const [node, keyString, isAdded] = this.stack.pop()! |
| 95 | |
| 96 | if (isAdded) { |
| 97 | const value = node.value |
| 98 | if (value !== undefined) { |
| 99 | const key = keyString + node.key |
| 100 | if (this.filter(key, value)) { |
| 101 | return { done: false, value: this.f(key, value) } |
| 102 | } |
| 103 | } |
| 104 | } else { |
| 105 | this.addToStack(node, keyString) |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | return { done: true, value: undefined } |
| 110 | } |
| 111 | |
| 112 | addToStack(node: Node<V>, keyString: string) { |
| 113 | if (node.right !== undefined) { |
| 114 | this.stack.push([node.right, keyString, false]) |
| 115 | } |
| 116 | if (node.mid !== undefined) { |
| 117 | this.stack.push([node.mid, keyString + node.key, false]) |
| 118 | } |
| 119 | this.stack.push([node, keyString, true]) |
| 120 | if (node.left !== undefined) { |
| 121 | this.stack.push([node.left, keyString, false]) |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | [Symbol.iterator](): IterableIterator<T> { |
| 126 | return new TrieIterator(this.trie, this.f, this.filter) |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | /** @internal */ |
| 131 | export const isTrie: { |
nothing calls this directly
no outgoing calls
no test coverage detected