list-toolkit 2.2.5 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -36
- package/llms-full.txt +743 -0
- package/llms.txt +100 -0
- package/package.json +40 -32
- package/src/cache/cache-fifo.d.ts +6 -0
- package/src/cache/cache-fifo.js +7 -4
- package/src/cache/cache-lfu.d.ts +18 -0
- package/src/cache/cache-lfu.js +18 -6
- package/src/cache/cache-lru.d.ts +74 -0
- package/src/cache/cache-lru.js +60 -5
- package/src/cache/cache-random.d.ts +20 -0
- package/src/cache/cache-random.js +17 -6
- package/src/cache/decorator.d.ts +46 -0
- package/src/cache/decorator.js +26 -2
- package/src/cache.d.ts +13 -0
- package/src/cache.js +7 -2
- package/src/ext-list.d.ts +3 -0
- package/src/ext-list.js +0 -2
- package/src/ext-slist.d.ts +3 -0
- package/src/ext-slist.js +0 -2
- package/src/ext-value-list.d.ts +3 -0
- package/src/ext-value-list.js +0 -2
- package/src/ext-value-slist.d.ts +3 -0
- package/src/ext-value-slist.js +0 -2
- package/src/heap/basics.d.ts +89 -0
- package/src/heap/basics.js +42 -5
- package/src/heap/leftist-heap.d.ts +107 -0
- package/src/heap/leftist-heap.js +54 -2
- package/src/heap/min-heap.d.ts +270 -0
- package/src/heap/min-heap.js +186 -2
- package/src/heap/skew-heap.d.ts +105 -0
- package/src/heap/skew-heap.js +54 -2
- package/src/heap.d.ts +3 -0
- package/src/heap.js +0 -2
- package/src/list/basics.d.ts +43 -0
- package/src/list/basics.js +26 -8
- package/src/list/core.d.ts +271 -0
- package/src/list/core.js +162 -7
- package/src/list/ext-value.d.ts +253 -0
- package/src/list/ext-value.js +40 -6
- package/src/list/ext.d.ts +242 -0
- package/src/list/ext.js +148 -10
- package/src/list/nodes.d.ts +336 -0
- package/src/list/nodes.js +141 -3
- package/src/list/ptr.d.ts +72 -0
- package/src/list/ptr.js +44 -2
- package/src/list/value.d.ts +292 -0
- package/src/list/value.js +47 -6
- package/src/list-helpers.d.ts +44 -0
- package/src/list-helpers.js +36 -3
- package/src/list-utils.d.ts +141 -0
- package/src/list-utils.js +89 -3
- package/src/list.d.ts +3 -0
- package/src/list.js +0 -2
- package/src/meta-utils.d.ts +212 -0
- package/src/meta-utils.js +152 -1
- package/src/nt-utils.d.ts +91 -0
- package/src/nt-utils.js +65 -4
- package/src/queue.d.ts +74 -0
- package/src/queue.js +28 -2
- package/src/slist/basics.d.ts +47 -0
- package/src/slist/basics.js +23 -8
- package/src/slist/core.d.ts +251 -0
- package/src/slist/core.js +151 -6
- package/src/slist/ext-value.d.ts +188 -0
- package/src/slist/ext-value.js +35 -6
- package/src/slist/ext.d.ts +182 -0
- package/src/slist/ext.js +114 -12
- package/src/slist/nodes.d.ts +361 -0
- package/src/slist/nodes.js +156 -3
- package/src/slist/ptr.d.ts +73 -0
- package/src/slist/ptr.js +45 -2
- package/src/slist/value.d.ts +246 -0
- package/src/slist/value.js +38 -6
- package/src/slist.d.ts +3 -0
- package/src/slist.js +0 -2
- package/src/stack.d.ts +59 -0
- package/src/stack.js +29 -3
- package/src/tree/splay-tree.d.ts +151 -0
- package/src/tree/splay-tree.js +94 -3
- package/src/value-list.d.ts +3 -0
- package/src/value-list.js +0 -2
- package/src/value-slist.d.ts +3 -0
- package/src/value-slist.js +0 -2
- package/cjs/cache/cache-fifo.js +0 -37
- package/cjs/cache/cache-lfu.js +0 -76
- package/cjs/cache/cache-lru.js +0 -100
- package/cjs/cache/cache-random.js +0 -77
- package/cjs/cache/decorator.js +0 -47
- package/cjs/cache.js +0 -27
- package/cjs/ext-list.js +0 -21
- package/cjs/ext-slist.js +0 -21
- package/cjs/ext-value-list.js +0 -21
- package/cjs/ext-value-slist.js +0 -21
- package/cjs/heap/basics.js +0 -63
- package/cjs/heap/leftist-heap.js +0 -124
- package/cjs/heap/min-heap.js +0 -294
- package/cjs/heap/skew-heap.js +0 -114
- package/cjs/heap.js +0 -21
- package/cjs/list/basics.js +0 -88
- package/cjs/list/core.js +0 -305
- package/cjs/list/ext-value.js +0 -88
- package/cjs/list/ext.js +0 -356
- package/cjs/list/nodes.js +0 -240
- package/cjs/list/ptr.js +0 -61
- package/cjs/list/value.js +0 -99
- package/cjs/list-helpers.js +0 -91
- package/cjs/list-utils.js +0 -141
- package/cjs/list.js +0 -21
- package/cjs/meta-utils.js +0 -171
- package/cjs/nt-utils.js +0 -132
- package/cjs/package.json +0 -1
- package/cjs/queue.js +0 -58
- package/cjs/slist/basics.js +0 -71
- package/cjs/slist/core.js +0 -362
- package/cjs/slist/ext-value.js +0 -82
- package/cjs/slist/ext.js +0 -336
- package/cjs/slist/nodes.js +0 -276
- package/cjs/slist/ptr.js +0 -87
- package/cjs/slist/value.js +0 -90
- package/cjs/slist.js +0 -21
- package/cjs/stack.js +0 -55
- package/cjs/tree/splay-tree.js +0 -362
- package/cjs/value-list.js +0 -21
- package/cjs/value-slist.js +0 -21
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import {ExtListBase, PtrBase, DllOptions, DllRange} from './nodes.js';
|
|
2
|
+
|
|
3
|
+
/** Pointer for navigating and mutating an external (headless) DLL. */
|
|
4
|
+
export class Ptr<T extends object = object> extends PtrBase<T> {
|
|
5
|
+
/** The external list this pointer belongs to. */
|
|
6
|
+
list: ExtList<T>;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param list - Owning list or another Ptr to copy.
|
|
10
|
+
* @param node - Target node.
|
|
11
|
+
*/
|
|
12
|
+
constructor(list: ExtList<T> | Ptr<T>, node?: T);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create a copy of this pointer.
|
|
16
|
+
* @returns A new Ptr referencing the same list and node.
|
|
17
|
+
*/
|
|
18
|
+
clone(): Ptr<T>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** External (headless) node-based doubly linked list. */
|
|
22
|
+
export class ExtList<T extends object = object> extends ExtListBase<T> {
|
|
23
|
+
/**
|
|
24
|
+
* Create a pointer to a node in this list.
|
|
25
|
+
* @param node - Target node, or `undefined` for the head.
|
|
26
|
+
* @returns A new Ptr, or `null` if the list is empty and no node given.
|
|
27
|
+
*/
|
|
28
|
+
makePtr(node?: T): Ptr<T> | null;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a pointer to the node after `prev`.
|
|
32
|
+
* @param prev - Preceding node, or `undefined` for the front.
|
|
33
|
+
* @returns A new Ptr.
|
|
34
|
+
*/
|
|
35
|
+
makePtrFromPrev(prev?: T): Ptr<T>;
|
|
36
|
+
|
|
37
|
+
// Ptr-style API
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Remove the current head node and advance to the next.
|
|
41
|
+
* @returns The removed node, or `null` if empty.
|
|
42
|
+
*/
|
|
43
|
+
removeCurrent(): T | null;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Remove the node before the head.
|
|
47
|
+
* @returns The removed node, or `null` if empty.
|
|
48
|
+
*/
|
|
49
|
+
removeNodeBefore(): T | null;
|
|
50
|
+
|
|
51
|
+
/** Alias for {@link removeNodeBefore}. */
|
|
52
|
+
removeBefore(): T | null;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Remove the node after the head.
|
|
56
|
+
* @returns The removed node, or `null` if empty.
|
|
57
|
+
*/
|
|
58
|
+
removeNodeAfter(): T | null;
|
|
59
|
+
|
|
60
|
+
/** Alias for {@link removeNodeAfter}. */
|
|
61
|
+
removeAfter(): T | null;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Insert a value before the head.
|
|
65
|
+
* @param value - Value or node to insert.
|
|
66
|
+
* @returns A Ptr to the inserted node.
|
|
67
|
+
*/
|
|
68
|
+
addBefore(value: T | PtrBase<T>): Ptr<T>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Insert a value after the head.
|
|
72
|
+
* @param value - Value or node to insert.
|
|
73
|
+
* @returns A Ptr to the inserted node.
|
|
74
|
+
*/
|
|
75
|
+
addAfter(value: T | PtrBase<T>): Ptr<T>;
|
|
76
|
+
|
|
77
|
+
/** Alias for {@link addAfter}. */
|
|
78
|
+
add(value: T | PtrBase<T>): Ptr<T>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Insert an existing node before the head.
|
|
82
|
+
* @param nodeOrPtr - Node or pointer to insert.
|
|
83
|
+
* @returns A Ptr to the inserted node.
|
|
84
|
+
*/
|
|
85
|
+
addNodeBefore(nodeOrPtr: T | PtrBase<T>): Ptr<T>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Insert an existing node after the head.
|
|
89
|
+
* @param nodeOrPtr - Node or pointer to insert.
|
|
90
|
+
* @returns A Ptr to the inserted node.
|
|
91
|
+
*/
|
|
92
|
+
addNodeAfter(nodeOrPtr: T | PtrBase<T>): Ptr<T>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Splice another external list's nodes before the head.
|
|
96
|
+
* @param extList - Compatible external list to consume.
|
|
97
|
+
* @returns A Ptr to the first inserted node, or `null` if empty.
|
|
98
|
+
*/
|
|
99
|
+
insertBefore(extList: ExtList<T>): Ptr<T> | null;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Splice another external list's nodes after the head.
|
|
103
|
+
* @param extList - Compatible external list to consume.
|
|
104
|
+
* @returns A Ptr to the first inserted node, or `null` if empty.
|
|
105
|
+
*/
|
|
106
|
+
insertAfter(extList: ExtList<T>): Ptr<T> | null;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Move a node to just before the head.
|
|
110
|
+
* @param nodeOrPtr - Node or pointer to move.
|
|
111
|
+
* @returns A Ptr to the moved node, or `this` if already at head.
|
|
112
|
+
*/
|
|
113
|
+
moveBefore(nodeOrPtr: T | PtrBase<T>): Ptr<T> | this;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Move a node to just after the head.
|
|
117
|
+
* @param nodeOrPtr - Node or pointer to move.
|
|
118
|
+
* @returns A Ptr to the moved node, or `this` if already at head.
|
|
119
|
+
*/
|
|
120
|
+
moveAfter(nodeOrPtr: T | PtrBase<T>): Ptr<T> | this;
|
|
121
|
+
|
|
122
|
+
// List-style API
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Remove all nodes.
|
|
126
|
+
* @param drop - If `true`, make each removed node stand-alone.
|
|
127
|
+
* @returns `this` for chaining.
|
|
128
|
+
*/
|
|
129
|
+
clear(drop?: boolean): this;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Remove a single node from the list.
|
|
133
|
+
* @param nodeOrPtr - Node or pointer to remove.
|
|
134
|
+
* @returns The removed node, or `null` if empty.
|
|
135
|
+
*/
|
|
136
|
+
removeNode(nodeOrPtr: T | PtrBase<T>): T | null;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Remove a range of nodes and optionally drop them.
|
|
140
|
+
* @param range - Range to remove.
|
|
141
|
+
* @param drop - If `true`, make each removed node stand-alone.
|
|
142
|
+
* @returns A new ExtList containing the removed nodes.
|
|
143
|
+
*/
|
|
144
|
+
removeRange(range?: DllRange<T>, drop?: boolean): ExtList<T>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Extract a range of nodes into a new list.
|
|
148
|
+
* @param range - Range to extract (defaults to the whole list).
|
|
149
|
+
* @returns A new ExtList containing the extracted nodes.
|
|
150
|
+
*/
|
|
151
|
+
extractRange(range?: DllRange<T>): ExtList<T>;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Extract nodes that satisfy a condition into a new list.
|
|
155
|
+
* @param condition - Predicate receiving each node.
|
|
156
|
+
* @returns A new ExtList containing the extracted nodes.
|
|
157
|
+
*/
|
|
158
|
+
extractBy(condition: (node: T) => boolean): ExtList<T>;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Reverse the order of all nodes in place.
|
|
162
|
+
* @returns `this` for chaining.
|
|
163
|
+
*/
|
|
164
|
+
reverse(): this;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Sort nodes in place using merge sort.
|
|
168
|
+
* @param lessFn - Comparison function returning `true` if `a` should precede `b`.
|
|
169
|
+
* @returns `this` for chaining.
|
|
170
|
+
*/
|
|
171
|
+
sort(lessFn: (a: T, b: T) => boolean): this;
|
|
172
|
+
|
|
173
|
+
/** Iterate over nodes starting from the head. */
|
|
174
|
+
[Symbol.iterator](): IterableIterator<T>;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Get an iterable over nodes in a range.
|
|
178
|
+
* @param range - Sub-range to iterate (defaults to the whole list).
|
|
179
|
+
* @returns An iterable iterator of nodes.
|
|
180
|
+
*/
|
|
181
|
+
getNodeIterator(range?: DllRange<T>): IterableIterator<T>;
|
|
182
|
+
|
|
183
|
+
/** Alias for {@link getNodeIterator}. */
|
|
184
|
+
getIterator(range?: DllRange<T>): IterableIterator<T>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get an iterable of Ptr objects over a range.
|
|
188
|
+
* @param range - Sub-range to iterate.
|
|
189
|
+
* @returns An iterable iterator of Ptrs.
|
|
190
|
+
*/
|
|
191
|
+
getPtrIterator(range?: DllRange<T>): IterableIterator<Ptr<T>>;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get an iterable over nodes in reverse order.
|
|
195
|
+
* @param range - Sub-range to iterate (defaults to the whole list).
|
|
196
|
+
* @returns An iterable iterator of nodes.
|
|
197
|
+
*/
|
|
198
|
+
getReverseNodeIterator(range?: DllRange<T>): IterableIterator<T>;
|
|
199
|
+
|
|
200
|
+
/** Alias for {@link getReverseNodeIterator}. */
|
|
201
|
+
getReverseIterator(range?: DllRange<T>): IterableIterator<T>;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Get an iterable of Ptr objects in reverse order.
|
|
205
|
+
* @param range - Sub-range to iterate.
|
|
206
|
+
* @returns An iterable iterator of Ptrs.
|
|
207
|
+
*/
|
|
208
|
+
getReversePtrIterator(range?: DllRange<T>): IterableIterator<Ptr<T>>;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Create a shallow clone of this list (shares nodes).
|
|
212
|
+
* @returns A new ExtList pointing to the same head.
|
|
213
|
+
*/
|
|
214
|
+
clone(): ExtList<T>;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Create an empty list with the same options.
|
|
218
|
+
* @param head - Optional initial head node.
|
|
219
|
+
* @returns A new ExtList.
|
|
220
|
+
*/
|
|
221
|
+
make(head?: T | null): ExtList<T>;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Create a list from values with the same options.
|
|
225
|
+
* @param values - Iterable of node objects.
|
|
226
|
+
* @returns A new ExtList.
|
|
227
|
+
*/
|
|
228
|
+
makeFrom(values: Iterable<T>): ExtList<T>;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Build an ExtList from an iterable of node objects.
|
|
232
|
+
* @param values - Iterable of nodes.
|
|
233
|
+
* @param options - Link property names.
|
|
234
|
+
* @returns A new ExtList.
|
|
235
|
+
*/
|
|
236
|
+
static from<T extends object = object>(values: Iterable<T>, options?: DllOptions): ExtList<T>;
|
|
237
|
+
|
|
238
|
+
/** The Ptr class associated with this list type. */
|
|
239
|
+
static Ptr: typeof Ptr;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export default ExtList;
|
package/src/list/ext.js
CHANGED
|
@@ -1,33 +1,53 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
import {ExtListBase, PtrBase} from './nodes.js';
|
|
4
2
|
import {pop, extract, splice, append} from './basics.js';
|
|
5
3
|
import {addAliases, normalizeIterator} from '../meta-utils.js';
|
|
6
4
|
|
|
5
|
+
/** Pointer for navigating and mutating an external doubly linked list. */
|
|
7
6
|
export class Ptr extends PtrBase {
|
|
7
|
+
/**
|
|
8
|
+
* @param {ExtList|Ptr} list - Owning list or another Ptr to copy.
|
|
9
|
+
* @param {object} [node] - Target node.
|
|
10
|
+
*/
|
|
8
11
|
constructor(list, node) {
|
|
9
12
|
super(list, node, ExtList);
|
|
10
13
|
this.node ||= this.list.head;
|
|
11
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Create a copy of this pointer.
|
|
17
|
+
* @returns {Ptr} A new Ptr referencing the same list and node.
|
|
18
|
+
*/
|
|
12
19
|
clone() {
|
|
13
20
|
return new Ptr(this);
|
|
14
21
|
}
|
|
15
22
|
}
|
|
16
23
|
|
|
24
|
+
/** External (headless) node-based doubly linked list. */
|
|
17
25
|
export class ExtList extends ExtListBase {
|
|
26
|
+
/**
|
|
27
|
+
* Create a pointer to a node in this list.
|
|
28
|
+
* @param {object} [node] - Target node, or `undefined` for the head.
|
|
29
|
+
* @returns {Ptr|null} A new Ptr, or `null` if the list is empty and no node given.
|
|
30
|
+
*/
|
|
18
31
|
makePtr(node) {
|
|
19
32
|
if (node && !this.isNodeLike(node)) throw new Error('"node" is not a compatible node');
|
|
20
33
|
node ||= this.head;
|
|
21
34
|
return node ? new Ptr(this, node) : null;
|
|
22
35
|
}
|
|
23
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Create a pointer to the node after `prev`.
|
|
39
|
+
* @param {object} [prev] - Preceding node, or `undefined` for the front.
|
|
40
|
+
* @returns {Ptr} A new Ptr.
|
|
41
|
+
*/
|
|
24
42
|
makePtrFromPrev(prev) {
|
|
25
43
|
if (prev && !this.isNodeLike(prev)) throw new Error('"prev" is not a compatible node');
|
|
26
44
|
return new Ptr(this, prev ? prev[this.nextName] : this.front);
|
|
27
45
|
}
|
|
28
46
|
|
|
29
|
-
|
|
30
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Remove the current head node and advance to the next.
|
|
49
|
+
* @returns {object|null} The removed node, or `null` if empty.
|
|
50
|
+
*/
|
|
31
51
|
removeCurrent() {
|
|
32
52
|
if (!this.head) return null;
|
|
33
53
|
if (this.head[this.nextName] === this.head) {
|
|
@@ -40,14 +60,27 @@ export class ExtList extends ExtListBase {
|
|
|
40
60
|
return result.extracted;
|
|
41
61
|
}
|
|
42
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Remove the node before the head.
|
|
65
|
+
* @returns {object|null} The removed node, or `null` if empty.
|
|
66
|
+
*/
|
|
43
67
|
removeNodeBefore() {
|
|
44
68
|
return this.head ? this.removeNode(this.head[this.prevName]) : null;
|
|
45
69
|
}
|
|
46
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Remove the node after the head.
|
|
73
|
+
* @returns {object|null} The removed node, or `null` if empty.
|
|
74
|
+
*/
|
|
47
75
|
removeNodeAfter() {
|
|
48
76
|
return this.head ? this.removeNode(this.head[this.nextName]) : null;
|
|
49
77
|
}
|
|
50
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Insert a value before the head.
|
|
81
|
+
* @param {*} value - Value or node to insert.
|
|
82
|
+
* @returns {Ptr} A Ptr to the inserted node.
|
|
83
|
+
*/
|
|
51
84
|
addBefore(value) {
|
|
52
85
|
const node = this.adoptValue(value);
|
|
53
86
|
if (this.head) {
|
|
@@ -58,6 +91,11 @@ export class ExtList extends ExtListBase {
|
|
|
58
91
|
return this.makePtr(node);
|
|
59
92
|
}
|
|
60
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Insert a value after the head.
|
|
96
|
+
* @param {*} value - Value or node to insert.
|
|
97
|
+
* @returns {Ptr} A Ptr to the inserted node.
|
|
98
|
+
*/
|
|
61
99
|
addAfter(value) {
|
|
62
100
|
const node = this.adoptValue(value);
|
|
63
101
|
if (this.head) {
|
|
@@ -68,6 +106,11 @@ export class ExtList extends ExtListBase {
|
|
|
68
106
|
return this.makePtr(node);
|
|
69
107
|
}
|
|
70
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Insert an existing node before the head.
|
|
111
|
+
* @param {object} nodeOrPtr - Node or pointer to insert.
|
|
112
|
+
* @returns {Ptr} A Ptr to the inserted node.
|
|
113
|
+
*/
|
|
71
114
|
addNodeBefore(nodeOrPtr) {
|
|
72
115
|
const node = this.adoptNode(nodeOrPtr);
|
|
73
116
|
if (this.head) {
|
|
@@ -78,6 +121,11 @@ export class ExtList extends ExtListBase {
|
|
|
78
121
|
return this.makePtr(node);
|
|
79
122
|
}
|
|
80
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Insert an existing node after the head.
|
|
126
|
+
* @param {object} nodeOrPtr - Node or pointer to insert.
|
|
127
|
+
* @returns {Ptr} A Ptr to the inserted node.
|
|
128
|
+
*/
|
|
81
129
|
addNodeAfter(nodeOrPtr) {
|
|
82
130
|
const node = this.adoptNode(nodeOrPtr);
|
|
83
131
|
if (this.head) {
|
|
@@ -88,6 +136,11 @@ export class ExtList extends ExtListBase {
|
|
|
88
136
|
return this.makePtr(node);
|
|
89
137
|
}
|
|
90
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Splice another external list's nodes before the head.
|
|
141
|
+
* @param {ExtListBase} extList - Compatible external list to consume.
|
|
142
|
+
* @returns {Ptr|null} A Ptr to the first inserted node, or `null` if empty.
|
|
143
|
+
*/
|
|
91
144
|
insertBefore(extList) {
|
|
92
145
|
if (!this.isCompatible(extList)) throw new Error('Incompatible lists');
|
|
93
146
|
|
|
@@ -100,6 +153,11 @@ export class ExtList extends ExtListBase {
|
|
|
100
153
|
return this.makePtr(head);
|
|
101
154
|
}
|
|
102
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Splice another external list's nodes after the head.
|
|
158
|
+
* @param {ExtListBase} extList - Compatible external list to consume.
|
|
159
|
+
* @returns {Ptr|null} A Ptr to the first inserted node, or `null` if empty.
|
|
160
|
+
*/
|
|
103
161
|
insertAfter(extList) {
|
|
104
162
|
if (!this.isCompatible(extList)) throw new Error('Incompatible lists');
|
|
105
163
|
|
|
@@ -112,6 +170,11 @@ export class ExtList extends ExtListBase {
|
|
|
112
170
|
return this.makePtr(head);
|
|
113
171
|
}
|
|
114
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Move a node to just before the head.
|
|
175
|
+
* @param {object} nodeOrPtr - Node or pointer to move.
|
|
176
|
+
* @returns {Ptr|ExtList} A Ptr to the moved node, or `this` if already at head.
|
|
177
|
+
*/
|
|
115
178
|
moveBefore(nodeOrPtr) {
|
|
116
179
|
const node = this.normalizeNode(nodeOrPtr);
|
|
117
180
|
|
|
@@ -130,6 +193,11 @@ export class ExtList extends ExtListBase {
|
|
|
130
193
|
return this.makePtr(node);
|
|
131
194
|
}
|
|
132
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Move a node to just after the head.
|
|
198
|
+
* @param {object} nodeOrPtr - Node or pointer to move.
|
|
199
|
+
* @returns {Ptr|ExtList} A Ptr to the moved node, or `this` if already at head.
|
|
200
|
+
*/
|
|
133
201
|
moveAfter(nodeOrPtr) {
|
|
134
202
|
const node = this.normalizeNode(nodeOrPtr);
|
|
135
203
|
|
|
@@ -148,8 +216,11 @@ export class ExtList extends ExtListBase {
|
|
|
148
216
|
return this.makePtr(node);
|
|
149
217
|
}
|
|
150
218
|
|
|
151
|
-
|
|
152
|
-
|
|
219
|
+
/**
|
|
220
|
+
* Remove all nodes.
|
|
221
|
+
* @param {boolean} [drop] - If `true`, make each removed node stand-alone.
|
|
222
|
+
* @returns {ExtList} `this` for chaining.
|
|
223
|
+
*/
|
|
153
224
|
clear(drop) {
|
|
154
225
|
if (drop) {
|
|
155
226
|
for (const current of this.getNodeIterator()) {
|
|
@@ -160,6 +231,11 @@ export class ExtList extends ExtListBase {
|
|
|
160
231
|
return this;
|
|
161
232
|
}
|
|
162
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Remove a node from the list.
|
|
236
|
+
* @param {object} nodeOrPtr - Node or pointer to remove.
|
|
237
|
+
* @returns {object|null} The removed node, or `null` if empty.
|
|
238
|
+
*/
|
|
163
239
|
removeNode(nodeOrPtr) {
|
|
164
240
|
if (!this.head) return null;
|
|
165
241
|
|
|
@@ -178,10 +254,21 @@ export class ExtList extends ExtListBase {
|
|
|
178
254
|
return pop(this, node).extracted;
|
|
179
255
|
}
|
|
180
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Remove a range and optionally drop nodes.
|
|
259
|
+
* @param {object} [range] - Range to remove.
|
|
260
|
+
* @param {boolean} [drop] - If `true`, make each removed node stand-alone.
|
|
261
|
+
* @returns {ExtList} A new ExtList containing the removed nodes.
|
|
262
|
+
*/
|
|
181
263
|
removeRange(range, drop) {
|
|
182
264
|
return this.extractRange(range).clear(drop);
|
|
183
265
|
}
|
|
184
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Extract a range into a new list.
|
|
269
|
+
* @param {object} [range={}] - Range to extract (defaults to the whole list).
|
|
270
|
+
* @returns {ExtList} A new ExtList containing the extracted nodes.
|
|
271
|
+
*/
|
|
185
272
|
extractRange(range = {}) {
|
|
186
273
|
range = this.normalizeRange(range);
|
|
187
274
|
const {from = this.head, to = from} = range;
|
|
@@ -195,6 +282,11 @@ export class ExtList extends ExtListBase {
|
|
|
195
282
|
return extracted;
|
|
196
283
|
}
|
|
197
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Extract nodes that satisfy a condition into a new list.
|
|
287
|
+
* @param {Function} condition - Predicate receiving each node.
|
|
288
|
+
* @returns {ExtList} A new ExtList containing the extracted nodes.
|
|
289
|
+
*/
|
|
198
290
|
extractBy(condition) {
|
|
199
291
|
const extracted = this.make();
|
|
200
292
|
if (this.isEmpty) return extracted;
|
|
@@ -209,6 +301,10 @@ export class ExtList extends ExtListBase {
|
|
|
209
301
|
return extracted;
|
|
210
302
|
}
|
|
211
303
|
|
|
304
|
+
/**
|
|
305
|
+
* Reverse the order of all nodes in place.
|
|
306
|
+
* @returns {ExtList} `this` for chaining.
|
|
307
|
+
*/
|
|
212
308
|
reverse() {
|
|
213
309
|
if (this.isOneOrEmpty) return this;
|
|
214
310
|
let current = this.head;
|
|
@@ -222,6 +318,11 @@ export class ExtList extends ExtListBase {
|
|
|
222
318
|
return this;
|
|
223
319
|
}
|
|
224
320
|
|
|
321
|
+
/**
|
|
322
|
+
* Sort nodes in place using merge sort.
|
|
323
|
+
* @param {Function} lessFn - Returns `true` if `a` should precede `b`.
|
|
324
|
+
* @returns {ExtList} `this` for chaining.
|
|
325
|
+
*/
|
|
225
326
|
sort(lessFn) {
|
|
226
327
|
if (this.isOneOrEmpty) return this;
|
|
227
328
|
|
|
@@ -267,8 +368,7 @@ export class ExtList extends ExtListBase {
|
|
|
267
368
|
return this.next();
|
|
268
369
|
}
|
|
269
370
|
|
|
270
|
-
|
|
271
|
-
|
|
371
|
+
/** Iterate over nodes starting from the head. */
|
|
272
372
|
[Symbol.iterator]() {
|
|
273
373
|
let current = this.head,
|
|
274
374
|
readyToStop = this.isEmpty;
|
|
@@ -283,6 +383,11 @@ export class ExtList extends ExtListBase {
|
|
|
283
383
|
});
|
|
284
384
|
}
|
|
285
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Get an iterable over nodes in a range.
|
|
388
|
+
* @param {object} [range={}] - Sub-range to iterate.
|
|
389
|
+
* @returns {Iterable} An iterable iterator of nodes.
|
|
390
|
+
*/
|
|
286
391
|
getNodeIterator(range = {}) {
|
|
287
392
|
range = this.normalizeRange(range);
|
|
288
393
|
const {from, to} = range;
|
|
@@ -304,10 +409,20 @@ export class ExtList extends ExtListBase {
|
|
|
304
409
|
};
|
|
305
410
|
}
|
|
306
411
|
|
|
412
|
+
/**
|
|
413
|
+
* Get an iterable of Ptr objects over a range.
|
|
414
|
+
* @param {object} [range] - Sub-range to iterate.
|
|
415
|
+
* @returns {Iterable} An iterable iterator of Ptrs.
|
|
416
|
+
*/
|
|
307
417
|
getPtrIterator(range) {
|
|
308
418
|
return mapIterator(this.getNodeIterator(range), node => new Ptr(this, node));
|
|
309
419
|
}
|
|
310
420
|
|
|
421
|
+
/**
|
|
422
|
+
* Get an iterable over nodes in reverse order.
|
|
423
|
+
* @param {object} [range={}] - Sub-range to iterate.
|
|
424
|
+
* @returns {Iterable} An iterable iterator of nodes.
|
|
425
|
+
*/
|
|
311
426
|
getReverseNodeIterator(range = {}) {
|
|
312
427
|
range = this.normalizeRange(range);
|
|
313
428
|
const {from, to} = range;
|
|
@@ -329,24 +444,47 @@ export class ExtList extends ExtListBase {
|
|
|
329
444
|
};
|
|
330
445
|
}
|
|
331
446
|
|
|
447
|
+
/**
|
|
448
|
+
* Get an iterable of Ptr objects in reverse order.
|
|
449
|
+
* @param {object} [range] - Sub-range to iterate.
|
|
450
|
+
* @returns {Iterable} An iterable iterator of Ptrs.
|
|
451
|
+
*/
|
|
332
452
|
getReversePtrIterator(range) {
|
|
333
453
|
return mapIterator(this.getReverseNodeIterator(range), node => new Ptr(this, node));
|
|
334
454
|
}
|
|
335
455
|
|
|
336
|
-
|
|
337
|
-
|
|
456
|
+
/**
|
|
457
|
+
* Create a shallow clone of this list.
|
|
458
|
+
* @returns {ExtList} A new ExtList pointing to the same head.
|
|
459
|
+
*/
|
|
338
460
|
clone() {
|
|
339
461
|
return new ExtList(this);
|
|
340
462
|
}
|
|
341
463
|
|
|
464
|
+
/**
|
|
465
|
+
* Create an empty list with the same options.
|
|
466
|
+
* @param {object|null} [head=null] - Optional initial head node.
|
|
467
|
+
* @returns {ExtList} A new ExtList.
|
|
468
|
+
*/
|
|
342
469
|
make(head = null) {
|
|
343
470
|
return new ExtList(head, this);
|
|
344
471
|
}
|
|
345
472
|
|
|
473
|
+
/**
|
|
474
|
+
* Create a list from values with the same options.
|
|
475
|
+
* @param {Iterable} values - Iterable of node objects.
|
|
476
|
+
* @returns {ExtList} A new ExtList.
|
|
477
|
+
*/
|
|
346
478
|
makeFrom(values) {
|
|
347
479
|
return ExtList.from(values, this);
|
|
348
480
|
}
|
|
349
481
|
|
|
482
|
+
/**
|
|
483
|
+
* Build an ExtList from an iterable of node objects.
|
|
484
|
+
* @param {Iterable} values - Iterable of nodes.
|
|
485
|
+
* @param {object} [options] - Link property names.
|
|
486
|
+
* @returns {ExtList} A new ExtList.
|
|
487
|
+
*/
|
|
350
488
|
static from(values, options) {
|
|
351
489
|
const list = new ExtList(null, options);
|
|
352
490
|
for (const value of values) {
|