collect-your-stuff 2.1.1 → 2.2.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 +32 -3241
- package/browser/collect-your-stuff.js +1585 -1193
- package/browser/collect-your-stuff.min.js +1 -1
- package/dist/collections/arrayable/ArrayElement.d.ts +33 -38
- package/dist/collections/arrayable/ArrayElement.js +64 -66
- package/dist/collections/arrayable/Arrayable.d.ts +107 -122
- package/dist/collections/arrayable/Arrayable.js +208 -223
- package/dist/collections/doubly-linked-list/DoubleLinker.d.ts +45 -50
- package/dist/collections/doubly-linked-list/DoubleLinker.js +71 -73
- package/dist/collections/doubly-linked-list/DoublyLinkedList.d.ts +108 -125
- package/dist/collections/doubly-linked-list/DoublyLinkedList.js +310 -327
- package/dist/collections/linked-list/LinkedList.d.ts +110 -126
- package/dist/collections/linked-list/LinkedList.js +283 -296
- package/dist/collections/linked-list/Linker.d.ts +41 -46
- package/dist/collections/linked-list/Linker.js +82 -84
- package/dist/collections/linked-tree-list/LinkedTreeList.d.ts +140 -159
- package/dist/collections/linked-tree-list/LinkedTreeList.js +274 -294
- package/dist/collections/linked-tree-list/TreeLinker.d.ts +65 -71
- package/dist/collections/linked-tree-list/TreeLinker.js +91 -94
- package/dist/collections/queue/Queue.d.ts +55 -59
- package/dist/collections/queue/Queue.js +114 -119
- package/dist/collections/queue/Queueable.d.ts +74 -83
- package/dist/collections/queue/Queueable.js +142 -146
- package/dist/collections/queue/TaskQueue.d.ts +59 -68
- package/dist/collections/queue/TaskQueue.js +128 -137
- package/dist/collections/scoped-collection/ScopedCollection.d.ts +42 -0
- package/dist/collections/scoped-collection/ScopedCollection.js +81 -0
- package/dist/collections/scoped-collection/ScopedCollection.min.js +1 -0
- package/dist/collections/stack/Stack.d.ts +60 -64
- package/dist/collections/stack/Stack.js +122 -127
- package/dist/collections/stack/Stackable.d.ts +52 -59
- package/dist/collections/stack/Stackable.js +81 -85
- package/dist/collections/stack/TaskStack.d.ts +56 -65
- package/dist/collections/stack/TaskStack.js +98 -107
- package/dist/main.d.ts +4 -5
- package/dist/main.js +9 -5
- package/dist/main.min.js +1 -1
- package/dist/recipes/ArrayIterator.d.ts +20 -20
- package/dist/recipes/ArrayIterator.js +39 -39
- package/dist/recipes/DoubleLinkerIterator.d.ts +18 -18
- package/dist/recipes/DoubleLinkerIterator.js +33 -33
- package/dist/recipes/IsArrayable.d.ts +85 -105
- package/dist/recipes/IsArrayable.js +5 -5
- package/dist/recipes/IsDoubleLinker.d.ts +14 -14
- package/dist/recipes/IsDoubleLinker.js +5 -5
- package/dist/recipes/IsElement.d.ts +14 -14
- package/dist/recipes/IsElement.js +5 -5
- package/dist/recipes/IsLinker.d.ts +10 -10
- package/dist/recipes/IsLinker.js +5 -5
- package/dist/recipes/IsQueue.d.ts +32 -37
- package/dist/recipes/IsQueue.js +5 -5
- package/dist/recipes/IsScopedCollection.d.ts +27 -0
- package/dist/recipes/IsScopedCollection.js +5 -0
- package/dist/recipes/IsScopedCollection.min.js +1 -0
- package/dist/recipes/IsStack.d.ts +31 -36
- package/dist/recipes/IsStack.js +5 -5
- package/dist/recipes/IsTree.d.ts +11 -11
- package/dist/recipes/IsTree.js +5 -5
- package/dist/recipes/IsTreeNode.d.ts +29 -29
- package/dist/recipes/IsTreeNode.js +5 -5
- package/dist/recipes/LinkerIterator.d.ts +18 -18
- package/dist/recipes/LinkerIterator.js +33 -33
- package/dist/recipes/Runnable.d.ts +42 -55
- package/dist/recipes/Runnable.js +63 -69
- package/dist/recipes/TreeLinkerIterator.d.ts +20 -20
- package/dist/recipes/TreeLinkerIterator.js +36 -36
- package/dist/recipes/recipes.d.ts +12 -15
- package/dist/recipes/recipes.js +19 -22
- package/dist/services/parseTree.d.ts +8 -9
- package/dist/services/parseTree.js +23 -24
- package/dist/services/parseTreeNext.d.ts +16 -17
- package/dist/services/parseTreeNext.js +41 -42
- package/dist/services/services.d.ts +10 -13
- package/dist/services/services.js +19 -22
- package/package.json +4 -4
|
@@ -1,327 +1,310 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', {
|
|
4
|
-
value: true
|
|
5
|
-
})
|
|
6
|
-
exports.DoublyLinkedList = void 0
|
|
7
|
-
require('core-js/modules/esnext.iterator.constructor.js')
|
|
8
|
-
require('core-js/modules/esnext.iterator.for-each.js')
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
newNode.next =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
newNode.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
*
|
|
186
|
-
* @param
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
if (node
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
let
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
current =
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
*/
|
|
312
|
-
[Symbol.iterator] () {
|
|
313
|
-
const current = this.first
|
|
314
|
-
return new _DoubleLinkerIterator.DoubleLinkerIterator(current)
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Convert an array into a DoublyLinkedList instance, return the new instance.
|
|
319
|
-
* @param {Array} [values=[]] An array of values which will be converted to linkers in this doubly-linked-list
|
|
320
|
-
* @param {IsDoubleLinker} [linkerClass=DoubleLinker] The class to use for each linker
|
|
321
|
-
* @param {IsArrayable<IsDoubleLinker>} [classType=LinkedList] Provide the type of IsArrayable to use.
|
|
322
|
-
* @returns {DoublyLinkedList}
|
|
323
|
-
*/
|
|
324
|
-
exports.DoublyLinkedList = DoublyLinkedList
|
|
325
|
-
DoublyLinkedList.fromArray = (values = [], linkerClass = _DoubleLinker.DoubleLinker, classType = DoublyLinkedList) => {
|
|
326
|
-
return _LinkedList.LinkedList.fromArray(values, linkerClass, classType)
|
|
327
|
-
}
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.DoublyLinkedList = void 0
|
|
7
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
8
|
+
require('core-js/modules/esnext.iterator.for-each.js')
|
|
9
|
+
const _DoubleLinker = require('./DoubleLinker')
|
|
10
|
+
const _DoubleLinkerIterator = require('../../recipes/DoubleLinkerIterator')
|
|
11
|
+
const _LinkedList = require('../linked-list/LinkedList')
|
|
12
|
+
/**
|
|
13
|
+
* doubly linked list.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* DoublyLinkedList represents a collection stored as a LinkedList with prev and next references.
|
|
18
|
+
* @extends LinkedList
|
|
19
|
+
*/
|
|
20
|
+
class DoublyLinkedList {
|
|
21
|
+
/**
|
|
22
|
+
* Create the new DoublyLinkedList instance.
|
|
23
|
+
* @param linkerClass The class used to wrap given data as linkers.
|
|
24
|
+
*/
|
|
25
|
+
constructor (linkerClass = _DoubleLinker.DoubleLinker) {
|
|
26
|
+
/** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
|
|
27
|
+
this.classType = DoublyLinkedList
|
|
28
|
+
/** A linker of the list (null when the list is empty); the head is found by walking back from it. */
|
|
29
|
+
this.innerList = null
|
|
30
|
+
/** Whether the inner list has been initialized (it can only be initialized once). */
|
|
31
|
+
this.initialized = false
|
|
32
|
+
/** The last linker, remembered so that adding to the end does not need to walk the whole list (null when not known yet). */
|
|
33
|
+
this.tailCache = null
|
|
34
|
+
/** The number of linkers, kept up to date by the list's own methods so that the length does not need to walk the whole list (null when not known yet). */
|
|
35
|
+
this.countCache = null
|
|
36
|
+
this.linkerClass = linkerClass
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Initialize the inner list, should only run once.
|
|
41
|
+
* @param initialList Give the list of double-linkers to start in this doubly linked-list.
|
|
42
|
+
*/
|
|
43
|
+
initialize (initialList) {
|
|
44
|
+
// Borrowed from LinkedList, which types its return as a LinkedList although it returns whatever list called it
|
|
45
|
+
return _LinkedList.LinkedList.prototype.initialize.call(this, initialList)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Retrieve the innerList used (the list itself, not a copy).
|
|
50
|
+
*/
|
|
51
|
+
get list () {
|
|
52
|
+
return this.innerList
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Retrieve the first DoubleLinker in the list.
|
|
57
|
+
*/
|
|
58
|
+
get first () {
|
|
59
|
+
let head = this.innerList
|
|
60
|
+
if (head === null) {
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
// innerList is normally the head already, walking back also finds anything linked on before it outside of this list
|
|
64
|
+
while (head.prev !== null) {
|
|
65
|
+
head = head.prev
|
|
66
|
+
}
|
|
67
|
+
this.innerList = head
|
|
68
|
+
return head
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Retrieve the last DoubleLinker in the list. The end is remembered, so this does not walk the list.
|
|
73
|
+
*/
|
|
74
|
+
get last () {
|
|
75
|
+
if (this.innerList === null) {
|
|
76
|
+
return null
|
|
77
|
+
}
|
|
78
|
+
let tail = this.tailCache !== null ? this.tailCache : this.innerList
|
|
79
|
+
// The remembered tail is normally the end already, walking on from it also finds anything linked on outside of this list
|
|
80
|
+
while (tail.next !== null) {
|
|
81
|
+
tail = tail.next
|
|
82
|
+
}
|
|
83
|
+
this.tailCache = tail
|
|
84
|
+
return tail
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Return the length of the list. It is kept up to date by the list's own methods, so this does not walk the list
|
|
89
|
+
* (call reset() after linkers were changed directly).
|
|
90
|
+
*/
|
|
91
|
+
get length () {
|
|
92
|
+
if (this.countCache === null) {
|
|
93
|
+
this.reset()
|
|
94
|
+
}
|
|
95
|
+
return this.countCache
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Insert a new node (or data) after a node.
|
|
100
|
+
* @param node The existing node as reference (which must be in this list, this is not checked), or null to insert at the start of the list
|
|
101
|
+
* @param newNode The new node to go after the existing node
|
|
102
|
+
*/
|
|
103
|
+
insertAfter (node, newNode) {
|
|
104
|
+
newNode = this.linkerClass.make(newNode, this.linkerClass)
|
|
105
|
+
if (node === null || typeof node === 'undefined') {
|
|
106
|
+
// After nothing means at the start of the list
|
|
107
|
+
const head = this.first
|
|
108
|
+
newNode.prev = null
|
|
109
|
+
newNode.next = head
|
|
110
|
+
if (head) {
|
|
111
|
+
head.prev = newNode
|
|
112
|
+
} else {
|
|
113
|
+
this.tailCache = newNode
|
|
114
|
+
}
|
|
115
|
+
this.innerList = newNode
|
|
116
|
+
} else {
|
|
117
|
+
// Ensure the next reference of this node is assigned to the new node
|
|
118
|
+
newNode.next = node.next
|
|
119
|
+
// Ensure this node is assigned as the prev reference of the new node
|
|
120
|
+
newNode.prev = node
|
|
121
|
+
// Then set this node's next reference to the new node
|
|
122
|
+
node.next = newNode
|
|
123
|
+
if (newNode.next) {
|
|
124
|
+
// Update the next reference to ensure circular reference for prev points to the new node
|
|
125
|
+
newNode.next.prev = newNode
|
|
126
|
+
} else {
|
|
127
|
+
this.tailCache = newNode
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (this.countCache !== null) {
|
|
131
|
+
++this.countCache
|
|
132
|
+
}
|
|
133
|
+
return this
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Insert a new node (or data) before a node.
|
|
138
|
+
* @param node The existing node as reference (which must be in this list, this is not checked), or null to insert at the end of the list
|
|
139
|
+
* @param newNode The new node to go before the existing node
|
|
140
|
+
*/
|
|
141
|
+
insertBefore (node, newNode) {
|
|
142
|
+
newNode = this.linkerClass.make(newNode, this.linkerClass)
|
|
143
|
+
if (node === null || typeof node === 'undefined') {
|
|
144
|
+
// Before nothing means at the end of the list
|
|
145
|
+
const tail = this.last
|
|
146
|
+
newNode.next = null
|
|
147
|
+
newNode.prev = tail
|
|
148
|
+
if (tail === null) {
|
|
149
|
+
this.innerList = newNode
|
|
150
|
+
} else {
|
|
151
|
+
tail.next = newNode
|
|
152
|
+
}
|
|
153
|
+
this.tailCache = newNode
|
|
154
|
+
} else {
|
|
155
|
+
// The new node will reference this prev node as prev
|
|
156
|
+
newNode.prev = node.prev
|
|
157
|
+
// The new node will reference this node as next
|
|
158
|
+
newNode.next = node
|
|
159
|
+
// This prev will reference the new node
|
|
160
|
+
node.prev = newNode
|
|
161
|
+
if (newNode.prev) {
|
|
162
|
+
// Update the prev reference to ensure circular reference for next points to the new node
|
|
163
|
+
newNode.prev.next = newNode
|
|
164
|
+
} else {
|
|
165
|
+
this.innerList = newNode
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (this.countCache !== null) {
|
|
169
|
+
++this.countCache
|
|
170
|
+
}
|
|
171
|
+
return this
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Add a node (or data) after the given (or last) node in the list.
|
|
176
|
+
* @param node The new node to add to the end of the list
|
|
177
|
+
* @param after The existing last node
|
|
178
|
+
*/
|
|
179
|
+
append (node, after = this.last) {
|
|
180
|
+
return this.insertAfter(after, node)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Add a node (or data) before the given (or first) node in the list.
|
|
185
|
+
* @param node The new node to add to the start of the list
|
|
186
|
+
* @param before The existing first node
|
|
187
|
+
*/
|
|
188
|
+
prepend (node, before = this.first) {
|
|
189
|
+
return this.insertBefore(before, node)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Remove a linker from this linked list.
|
|
194
|
+
* @param node The node we wish to remove (and it will be returned after removal)
|
|
195
|
+
*/
|
|
196
|
+
remove (node) {
|
|
197
|
+
if (node === null || typeof node === 'undefined') {
|
|
198
|
+
return null
|
|
199
|
+
}
|
|
200
|
+
if (node.prev) {
|
|
201
|
+
// The previous node will reference this next node
|
|
202
|
+
node.prev.next = node.next
|
|
203
|
+
}
|
|
204
|
+
if (node.next) {
|
|
205
|
+
// The next node will reference this previous node
|
|
206
|
+
node.next.prev = node.prev
|
|
207
|
+
}
|
|
208
|
+
// The list finds its head by walking from innerList, so it must not keep pointing at the node being removed. For the
|
|
209
|
+
// last remaining node there is nothing to walk to, which would otherwise leave the removed node in the list.
|
|
210
|
+
if (this.innerList === node) {
|
|
211
|
+
this.innerList = node.next || node.prev || null
|
|
212
|
+
}
|
|
213
|
+
if (this.tailCache === node) {
|
|
214
|
+
this.tailCache = node.prev
|
|
215
|
+
}
|
|
216
|
+
if (this.innerList === null) {
|
|
217
|
+
this.tailCache = null
|
|
218
|
+
}
|
|
219
|
+
if (this.countCache !== null) {
|
|
220
|
+
--this.countCache
|
|
221
|
+
}
|
|
222
|
+
return node
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Refresh all references (the head, the end and the length) by walking the list once, and return the head. The list's
|
|
227
|
+
* own methods keep these up to date, so this is only needed after linkers were changed directly.
|
|
228
|
+
*/
|
|
229
|
+
reset () {
|
|
230
|
+
// Start at the pointer for the list
|
|
231
|
+
let pointer = this.innerList
|
|
232
|
+
if (pointer === null) {
|
|
233
|
+
this.countCache = 0
|
|
234
|
+
this.tailCache = null
|
|
235
|
+
return null
|
|
236
|
+
}
|
|
237
|
+
// Follow references back to the beginning
|
|
238
|
+
while (pointer.prev !== null) {
|
|
239
|
+
pointer = pointer.prev
|
|
240
|
+
}
|
|
241
|
+
// We are pointing to the true head, now count along to the end to find the tail and the length
|
|
242
|
+
this.innerList = pointer
|
|
243
|
+
let count = 0
|
|
244
|
+
let tail = pointer
|
|
245
|
+
let current = pointer
|
|
246
|
+
while (current !== null) {
|
|
247
|
+
++count
|
|
248
|
+
tail = current
|
|
249
|
+
current = current.next
|
|
250
|
+
}
|
|
251
|
+
this.countCache = count
|
|
252
|
+
this.tailCache = tail
|
|
253
|
+
return pointer
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Retrieve a DoubleLinker item from this list by numeric index, otherwise return null.
|
|
258
|
+
* @param index The integer number for retrieving a node by position.
|
|
259
|
+
*/
|
|
260
|
+
item (index) {
|
|
261
|
+
if (index >= 0) {
|
|
262
|
+
// For a positive index, start from the beginning of the list until the current item counter equals our index
|
|
263
|
+
let current = this.first
|
|
264
|
+
let currentIndex = -1
|
|
265
|
+
while (++currentIndex < index && current !== null) {
|
|
266
|
+
current = current.next
|
|
267
|
+
}
|
|
268
|
+
return currentIndex === index ? current : null
|
|
269
|
+
}
|
|
270
|
+
// For a negative index, get the delta of index and length, then go backwards until we reach that delta
|
|
271
|
+
let current = this.last
|
|
272
|
+
let currentIndex = this.length
|
|
273
|
+
const calculatedIndex = this.length + index
|
|
274
|
+
if (calculatedIndex < 0) {
|
|
275
|
+
return null
|
|
276
|
+
}
|
|
277
|
+
while (--currentIndex > calculatedIndex && current !== null) {
|
|
278
|
+
current = current.prev
|
|
279
|
+
}
|
|
280
|
+
return currentIndex === calculatedIndex ? current : null
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Be able to run forEach on this DoublyLinkedList to iterate over the DoubleLinker Items.
|
|
285
|
+
* @param callback The function to call for-each double linker
|
|
286
|
+
* @param thisArg Optional, 'this' reference
|
|
287
|
+
* @returns The list which was iterated.
|
|
288
|
+
*/
|
|
289
|
+
forEach (callback, thisArg = this) {
|
|
290
|
+
return _LinkedList.LinkedList.prototype.forEach.call(this, callback, thisArg)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Be able to iterate over this class.
|
|
295
|
+
*/
|
|
296
|
+
[Symbol.iterator] () {
|
|
297
|
+
const current = this.first
|
|
298
|
+
return new _DoubleLinkerIterator.DoubleLinkerIterator(current)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Convert an array into a DoublyLinkedList instance, return the new instance.
|
|
303
|
+
* @param values An array of values which will be converted to linkers in this doubly-linked-list
|
|
304
|
+
* @param linkerClass The class to use for each linker
|
|
305
|
+
* @param classType Provide the type of IsArrayable to use.
|
|
306
|
+
*/
|
|
307
|
+
exports.DoublyLinkedList = DoublyLinkedList
|
|
308
|
+
DoublyLinkedList.fromArray = (values = [], linkerClass = _DoubleLinker.DoubleLinker, classType = DoublyLinkedList) => {
|
|
309
|
+
return _LinkedList.LinkedList.fromArray(values, linkerClass, classType)
|
|
310
|
+
}
|