list-toolkit 1.0.1 → 2.0.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 +93 -407
- package/cjs/cache/cache-fifo.js +37 -0
- package/cjs/cache/cache-lfu.js +76 -0
- package/cjs/cache/cache-lru.js +100 -0
- package/cjs/cache/cache-random.js +77 -0
- package/cjs/cache/decorator.js +47 -0
- package/cjs/cache.js +28 -0
- package/cjs/ext-list.js +22 -0
- package/cjs/ext-slist.js +22 -0
- package/cjs/ext-value-list.js +22 -0
- package/cjs/ext-value-slist.js +22 -0
- package/cjs/{MinHeap.js → heap/min-heap.js} +77 -10
- package/cjs/heap.js +22 -0
- package/cjs/list/basics.js +88 -0
- package/cjs/list/core.js +305 -0
- package/cjs/list/ext-value.js +89 -0
- package/cjs/list/ext.js +356 -0
- package/cjs/list/nodes.js +240 -0
- package/cjs/list/ptr.js +61 -0
- package/cjs/list/value.js +100 -0
- package/cjs/list-helpers.js +91 -0
- package/cjs/list-utils.js +141 -0
- package/cjs/list.js +22 -0
- package/cjs/meta-utils.js +167 -0
- package/cjs/nt-utils.js +132 -0
- package/cjs/queue.js +58 -0
- package/cjs/slist/basics.js +71 -0
- package/cjs/slist/core.js +362 -0
- package/cjs/slist/ext-value.js +83 -0
- package/cjs/slist/ext.js +336 -0
- package/cjs/slist/nodes.js +276 -0
- package/cjs/slist/ptr.js +87 -0
- package/cjs/slist/value.js +91 -0
- package/cjs/slist.js +22 -0
- package/cjs/stack.js +55 -0
- package/cjs/value-list.js +22 -0
- package/cjs/value-slist.js +22 -0
- package/package.json +10 -8
- package/src/cache/cache-fifo.js +27 -0
- package/src/cache/cache-lfu.js +63 -0
- package/src/cache/cache-lru.js +87 -0
- package/src/cache/cache-random.js +73 -0
- package/src/cache/decorator.js +45 -0
- package/src/cache.js +9 -0
- package/src/ext-list.js +6 -0
- package/src/ext-slist.js +6 -0
- package/src/ext-value-list.js +6 -0
- package/src/ext-value-slist.js +6 -0
- package/src/{MinHeap.js → heap/min-heap.js} +91 -9
- package/src/heap.js +6 -0
- package/src/list/basics.js +64 -0
- package/src/list/core.js +314 -0
- package/src/list/ext-value.js +81 -0
- package/src/list/ext.js +370 -0
- package/src/list/nodes.js +262 -0
- package/src/list/ptr.js +58 -0
- package/src/list/value.js +88 -0
- package/src/list-helpers.js +80 -0
- package/src/list-utils.js +140 -0
- package/src/list.js +6 -0
- package/src/meta-utils.js +147 -0
- package/src/nt-utils.js +85 -0
- package/src/queue.js +52 -0
- package/src/slist/basics.js +47 -0
- package/src/slist/core.js +364 -0
- package/src/slist/ext-value.js +74 -0
- package/src/slist/ext.js +331 -0
- package/src/slist/nodes.js +290 -0
- package/src/slist/ptr.js +77 -0
- package/src/slist/value.js +75 -0
- package/src/slist.js +6 -0
- package/src/stack.js +52 -0
- package/src/value-list.js +6 -0
- package/src/value-slist.js +6 -0
- package/cjs/Cache.js +0 -70
- package/cjs/List.js +0 -291
- package/cjs/ListHead.js +0 -308
- package/cjs/SList.js +0 -336
- package/cjs/SListHead.js +0 -363
- package/cjs/utils.js +0 -43
- package/src/Cache.js +0 -61
- package/src/List.js +0 -303
- package/src/ListHead.js +0 -304
- package/src/SList.js +0 -329
- package/src/SListHead.js +0 -353
- package/src/utils.js +0 -35
package/cjs/ListHead.js
DELETED
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _utils = require("./utils.js");
|
|
8
|
-
class ListHead {
|
|
9
|
-
constructor(head = null, options) {
|
|
10
|
-
if (head instanceof ListHead) {
|
|
11
|
-
({
|
|
12
|
-
nextName: this.nextName,
|
|
13
|
-
prevName: this.prevName,
|
|
14
|
-
head: this.head
|
|
15
|
-
} = head);
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
(0, _utils.copyOptions)(this, ListHead.defaults, options);
|
|
19
|
-
if (head instanceof ListHead.Unsafe) {
|
|
20
|
-
this.head = head.head;
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (head) {
|
|
24
|
-
switch ((head[this.nextName] ? 2 : 0) + (head[this.prevName] ? 1 : 0)) {
|
|
25
|
-
case 0:
|
|
26
|
-
this.adopt(head);
|
|
27
|
-
break;
|
|
28
|
-
case 3:
|
|
29
|
-
// do nothing
|
|
30
|
-
break;
|
|
31
|
-
default:
|
|
32
|
-
throw new Error(`head is not an empty object nor a list with required properties (${this.nextName}, ${this.prevName})`);
|
|
33
|
-
}
|
|
34
|
-
} else {
|
|
35
|
-
head = this.makeNode();
|
|
36
|
-
}
|
|
37
|
-
this.head = head;
|
|
38
|
-
}
|
|
39
|
-
get isEmpty() {
|
|
40
|
-
return this.head[this.nextName] === this.head;
|
|
41
|
-
}
|
|
42
|
-
get front() {
|
|
43
|
-
return this.head[this.nextName];
|
|
44
|
-
}
|
|
45
|
-
get back() {
|
|
46
|
-
return this.head[this.prevName];
|
|
47
|
-
}
|
|
48
|
-
getLength() {
|
|
49
|
-
let n = 0;
|
|
50
|
-
for (let p = this.head[this.nextName]; p !== this.head; ++n, p = p[this.nextName]);
|
|
51
|
-
return n;
|
|
52
|
-
}
|
|
53
|
-
popFront() {
|
|
54
|
-
if (this.head[this.prevName] !== this.head) {
|
|
55
|
-
return ListHead.pop(this, this.head[this.nextName]).node;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
popBack() {
|
|
59
|
-
if (this.head[this.prevName] !== this.head) {
|
|
60
|
-
return ListHead.pop(this, this.head[this.prevName]).node;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
pushFront(node) {
|
|
64
|
-
this.adopt(node);
|
|
65
|
-
ListHead.splice(this, this.head[this.nextName], node);
|
|
66
|
-
return this;
|
|
67
|
-
}
|
|
68
|
-
pushBack(node) {
|
|
69
|
-
this.adopt(node);
|
|
70
|
-
ListHead.splice(this, this.head, node);
|
|
71
|
-
return this;
|
|
72
|
-
}
|
|
73
|
-
appendFront(list) {
|
|
74
|
-
if (list instanceof ListHead) {
|
|
75
|
-
list = list.head;
|
|
76
|
-
}
|
|
77
|
-
if (list[this.prevName] !== list) {
|
|
78
|
-
ListHead.splice(this, this.head[this.nextName], ListHead.extract(this, list[this.nextName], list[this.prevName]));
|
|
79
|
-
}
|
|
80
|
-
return this;
|
|
81
|
-
}
|
|
82
|
-
appendBack(list) {
|
|
83
|
-
if (list instanceof ListHead) {
|
|
84
|
-
list = list.head;
|
|
85
|
-
}
|
|
86
|
-
if (list[this.prevName] !== list) {
|
|
87
|
-
ListHead.splice(this, this.head, ListHead.extract(this, list[this.nextName], list[this.prevName]));
|
|
88
|
-
}
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
moveToFront(node) {
|
|
92
|
-
if (this.head[this.nextName] !== node) {
|
|
93
|
-
ListHead.splice(this, this.head[this.nextName], ListHead.extract(this, node, node));
|
|
94
|
-
}
|
|
95
|
-
return this;
|
|
96
|
-
}
|
|
97
|
-
moveToBack(node) {
|
|
98
|
-
if (this.head[this.prevName] !== node) {
|
|
99
|
-
ListHead.splice(this, this.head, ListHead.extract(this, node, node));
|
|
100
|
-
}
|
|
101
|
-
return this;
|
|
102
|
-
}
|
|
103
|
-
clear(drop) {
|
|
104
|
-
if (drop) {
|
|
105
|
-
while (!this.isEmpty) this.popFront();
|
|
106
|
-
} else {
|
|
107
|
-
this.head[this.prevName] = this.head[this.nextName] = this.head;
|
|
108
|
-
}
|
|
109
|
-
return this;
|
|
110
|
-
}
|
|
111
|
-
remove(from, to = from) {
|
|
112
|
-
ListHead.extract(this, from, to);
|
|
113
|
-
return this;
|
|
114
|
-
}
|
|
115
|
-
extract(from, to) {
|
|
116
|
-
return this.make(ListHead.splice(this, this.makeNode(), ListHead.extract(this, from, to)));
|
|
117
|
-
}
|
|
118
|
-
reverse() {
|
|
119
|
-
const list = this.head;
|
|
120
|
-
let next = list[this.nextName];
|
|
121
|
-
list[this.nextName] = list[this.prevName];
|
|
122
|
-
list[this.prevName] = next;
|
|
123
|
-
while (next !== list) {
|
|
124
|
-
const node = next;
|
|
125
|
-
next = node[this.nextName];
|
|
126
|
-
node[this.nextName] = node[this.prevName];
|
|
127
|
-
node[this.prevName] = next;
|
|
128
|
-
}
|
|
129
|
-
return this;
|
|
130
|
-
}
|
|
131
|
-
sort(compareFn) {
|
|
132
|
-
let prev = this.head;
|
|
133
|
-
for (const node of Array.from(this).sort(compareFn)) {
|
|
134
|
-
prev[this.nextName] = node;
|
|
135
|
-
node[this.prevName] = prev;
|
|
136
|
-
prev = node;
|
|
137
|
-
}
|
|
138
|
-
this.head[this.prevName] = prev;
|
|
139
|
-
prev[this.nextName] = this.head;
|
|
140
|
-
return this;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// iterators
|
|
144
|
-
|
|
145
|
-
[Symbol.iterator]() {
|
|
146
|
-
let current = this.head[this.nextName];
|
|
147
|
-
return {
|
|
148
|
-
next: () => {
|
|
149
|
-
if (current === this.head) return {
|
|
150
|
-
done: true
|
|
151
|
-
};
|
|
152
|
-
const value = current;
|
|
153
|
-
current = current[this.nextName];
|
|
154
|
-
return {
|
|
155
|
-
value
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
getIterable(from, to) {
|
|
161
|
-
return {
|
|
162
|
-
[Symbol.iterator]: () => {
|
|
163
|
-
let current = from || this.head[this.nextName];
|
|
164
|
-
const stop = to ? to[this.nextName] : this.head;
|
|
165
|
-
return {
|
|
166
|
-
next: () => {
|
|
167
|
-
if (current === stop) return {
|
|
168
|
-
done: true
|
|
169
|
-
};
|
|
170
|
-
const value = current;
|
|
171
|
-
current = current[this.nextName];
|
|
172
|
-
return {
|
|
173
|
-
value
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
getReverseIterable(from, to) {
|
|
181
|
-
return {
|
|
182
|
-
[Symbol.iterator]: () => {
|
|
183
|
-
let current = to || this.head[this.prevName];
|
|
184
|
-
const stop = from ? from[this.prevName] : this.head;
|
|
185
|
-
return {
|
|
186
|
-
next: () => {
|
|
187
|
-
if (current === stop) return {
|
|
188
|
-
done: true
|
|
189
|
-
};
|
|
190
|
-
const value = current;
|
|
191
|
-
current = current[this.prevName];
|
|
192
|
-
return {
|
|
193
|
-
value
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// static utilities
|
|
202
|
-
|
|
203
|
-
static pop({
|
|
204
|
-
nextName,
|
|
205
|
-
prevName
|
|
206
|
-
}, node) {
|
|
207
|
-
const list = node[nextName];
|
|
208
|
-
// the next line stitches the rest of the list excluding the node, and collapse the node into a one-node list
|
|
209
|
-
node[prevName] = node[nextName] = ({
|
|
210
|
-
[nextName]: node[prevName][nextName],
|
|
211
|
-
[prevName]: node[nextName][prevName]
|
|
212
|
-
} = node);
|
|
213
|
-
return {
|
|
214
|
-
node,
|
|
215
|
-
list
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
static extract({
|
|
219
|
-
nextName,
|
|
220
|
-
prevName
|
|
221
|
-
}, from, to) {
|
|
222
|
-
const prev = from[prevName],
|
|
223
|
-
next = to[nextName];
|
|
224
|
-
prev[nextName] = next;
|
|
225
|
-
next[prevName] = prev;
|
|
226
|
-
from[prevName] = to;
|
|
227
|
-
to[nextName] = from;
|
|
228
|
-
return from;
|
|
229
|
-
}
|
|
230
|
-
static splice({
|
|
231
|
-
nextName,
|
|
232
|
-
prevName
|
|
233
|
-
}, list1, list2) {
|
|
234
|
-
const tail1 = list1[prevName],
|
|
235
|
-
tail2 = list2[prevName];
|
|
236
|
-
tail1[nextName] = list2;
|
|
237
|
-
list2[prevName] = tail1;
|
|
238
|
-
tail2[nextName] = list1;
|
|
239
|
-
list1[prevName] = tail2;
|
|
240
|
-
return list1;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// node helpers
|
|
244
|
-
|
|
245
|
-
makeNode() {
|
|
246
|
-
const node = {};
|
|
247
|
-
node[this.nextName] = node[this.prevName] = node;
|
|
248
|
-
return node;
|
|
249
|
-
}
|
|
250
|
-
adopt(node) {
|
|
251
|
-
if (node[this.nextName] || node[this.prevName]) {
|
|
252
|
-
if (node[this.nextName] === node && node[this.prevName] === node) return node;
|
|
253
|
-
throw new Error('node is already a part of a list, or there is a name clash');
|
|
254
|
-
}
|
|
255
|
-
node[this.nextName] = node[this.prevName] = node;
|
|
256
|
-
return node;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// helpers
|
|
260
|
-
|
|
261
|
-
clone() {
|
|
262
|
-
return new ListHead(this);
|
|
263
|
-
}
|
|
264
|
-
make(newHead = null) {
|
|
265
|
-
return new ListHead(newHead, this);
|
|
266
|
-
}
|
|
267
|
-
makeFrom(values) {
|
|
268
|
-
return ListHead.from(values, this);
|
|
269
|
-
}
|
|
270
|
-
pushValuesFront(values) {
|
|
271
|
-
for (const value of values) {
|
|
272
|
-
this.pushFront(value);
|
|
273
|
-
}
|
|
274
|
-
return this;
|
|
275
|
-
}
|
|
276
|
-
pushValuesBack(values) {
|
|
277
|
-
for (const value of values) {
|
|
278
|
-
this.pushBack(value);
|
|
279
|
-
}
|
|
280
|
-
return this;
|
|
281
|
-
}
|
|
282
|
-
appendValuesFront(values) {
|
|
283
|
-
return this.appendFront(ListHead.from(values, this));
|
|
284
|
-
}
|
|
285
|
-
appendValuesBack(values) {
|
|
286
|
-
return this.appendBack(ListHead.from(values, this));
|
|
287
|
-
}
|
|
288
|
-
static from(values, options) {
|
|
289
|
-
const list = new ListHead(null, options);
|
|
290
|
-
for (const value of values) {
|
|
291
|
-
list.pushBack(value);
|
|
292
|
-
}
|
|
293
|
-
return list;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
ListHead.defaults = {
|
|
297
|
-
nextName: 'next',
|
|
298
|
-
prevName: 'prev'
|
|
299
|
-
};
|
|
300
|
-
ListHead.prototype.pop = ListHead.prototype.popFront;
|
|
301
|
-
ListHead.prototype.push = ListHead.prototype.pushFront;
|
|
302
|
-
ListHead.prototype.append = ListHead.prototype.appendBack;
|
|
303
|
-
ListHead.Unsafe = class {
|
|
304
|
-
constructor(head) {
|
|
305
|
-
this.head = head;
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
var _default = exports.default = ListHead;
|
package/cjs/SList.js
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
class SListNode {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.next = this;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
const pop = prev => {
|
|
13
|
-
const node = prev.next;
|
|
14
|
-
prev.next = node.next;
|
|
15
|
-
node.next = node;
|
|
16
|
-
return {
|
|
17
|
-
node,
|
|
18
|
-
list: prev
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
const extract = (prevFrom, nodeTo) => {
|
|
22
|
-
const node = prevFrom.next;
|
|
23
|
-
if (prevFrom === nodeTo) return {
|
|
24
|
-
prev: prevFrom,
|
|
25
|
-
node
|
|
26
|
-
};
|
|
27
|
-
prevFrom.next = nodeTo.next;
|
|
28
|
-
nodeTo.next = node;
|
|
29
|
-
return {
|
|
30
|
-
prev: nodeTo,
|
|
31
|
-
node
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
const splice = (prev1, {
|
|
35
|
-
prev,
|
|
36
|
-
node
|
|
37
|
-
}) => {
|
|
38
|
-
prev.next = prev1.next;
|
|
39
|
-
prev1.next = node;
|
|
40
|
-
return prev1;
|
|
41
|
-
};
|
|
42
|
-
const getPrevPrev = (list, node) => {
|
|
43
|
-
let prev = list,
|
|
44
|
-
current = prev.next;
|
|
45
|
-
while (current.next !== list) {
|
|
46
|
-
if (node && current.next === node) return prev;
|
|
47
|
-
prev = current;
|
|
48
|
-
current = prev.next;
|
|
49
|
-
}
|
|
50
|
-
if (node) {
|
|
51
|
-
if (list.next === node) return current;
|
|
52
|
-
throw new Error('node does not belong to the list');
|
|
53
|
-
}
|
|
54
|
-
return prev;
|
|
55
|
-
};
|
|
56
|
-
const getPrev = (list, node) => {
|
|
57
|
-
return getPrevPrev(list, node).next;
|
|
58
|
-
};
|
|
59
|
-
class SListValueNode extends SListNode {
|
|
60
|
-
constructor(value) {
|
|
61
|
-
super();
|
|
62
|
-
this.value = value;
|
|
63
|
-
}
|
|
64
|
-
addAfter(value) {
|
|
65
|
-
const node = new SListValueNode(value);
|
|
66
|
-
splice(this, {
|
|
67
|
-
prev: node,
|
|
68
|
-
node
|
|
69
|
-
});
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
insertAfter(list) {
|
|
73
|
-
const node = getPrev(pop(list).list);
|
|
74
|
-
splice(this, {
|
|
75
|
-
prev: node,
|
|
76
|
-
node
|
|
77
|
-
});
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
class SList extends SListNode {
|
|
82
|
-
get isEmpty() {
|
|
83
|
-
return this.next === this;
|
|
84
|
-
}
|
|
85
|
-
get front() {
|
|
86
|
-
return this.next;
|
|
87
|
-
}
|
|
88
|
-
getBack() {
|
|
89
|
-
return getPrev(this);
|
|
90
|
-
}
|
|
91
|
-
getLength() {
|
|
92
|
-
let n = 0;
|
|
93
|
-
for (let p = this.next; p !== this; ++n, p = p.next);
|
|
94
|
-
return n;
|
|
95
|
-
}
|
|
96
|
-
getPtr() {
|
|
97
|
-
return new SList.SListPtr(this);
|
|
98
|
-
}
|
|
99
|
-
popFront() {
|
|
100
|
-
if (this.next !== this) {
|
|
101
|
-
return pop(this).node.value;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
popBack() {
|
|
105
|
-
if (this.next !== this) {
|
|
106
|
-
const prevLast = getPrevPrev(this);
|
|
107
|
-
return pop(prevLast).node.value;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
pushFront(value) {
|
|
111
|
-
const node = new SListValueNode(value);
|
|
112
|
-
splice(this, {
|
|
113
|
-
prev: node,
|
|
114
|
-
node
|
|
115
|
-
});
|
|
116
|
-
return this;
|
|
117
|
-
}
|
|
118
|
-
pushBack(value) {
|
|
119
|
-
const node = new SListValueNode(value),
|
|
120
|
-
last = getPrev(this);
|
|
121
|
-
splice(last, {
|
|
122
|
-
prev: node,
|
|
123
|
-
node
|
|
124
|
-
});
|
|
125
|
-
return this;
|
|
126
|
-
}
|
|
127
|
-
appendFront(list) {
|
|
128
|
-
if (list.next === list) return this;
|
|
129
|
-
let prevFrom = list,
|
|
130
|
-
nodeTo = getPrev(list);
|
|
131
|
-
splice(this, extract(prevFrom, nodeTo));
|
|
132
|
-
return this;
|
|
133
|
-
}
|
|
134
|
-
appendBack(list) {
|
|
135
|
-
if (list.next === list) return this;
|
|
136
|
-
let prevFrom = list,
|
|
137
|
-
nodeTo = getPrev(list),
|
|
138
|
-
last = getPrev(this);
|
|
139
|
-
splice(last, extract(prevFrom, nodeTo));
|
|
140
|
-
return this;
|
|
141
|
-
}
|
|
142
|
-
moveToFront(node) {
|
|
143
|
-
let prev;
|
|
144
|
-
if (node instanceof SList.SListPtr) {
|
|
145
|
-
prev = node.prev;
|
|
146
|
-
node = node.node;
|
|
147
|
-
if (this.next === node) return this;
|
|
148
|
-
} else {
|
|
149
|
-
if (this.next === node) return this;
|
|
150
|
-
prev = getPrev(this, node);
|
|
151
|
-
}
|
|
152
|
-
splice(this, extract(prev, node));
|
|
153
|
-
return this;
|
|
154
|
-
}
|
|
155
|
-
moveToBack(node) {
|
|
156
|
-
let prev;
|
|
157
|
-
if (node instanceof SList.SListPtr) {
|
|
158
|
-
prev = node.prev;
|
|
159
|
-
node = node.node;
|
|
160
|
-
} else {
|
|
161
|
-
prev = getPrev(this, node);
|
|
162
|
-
}
|
|
163
|
-
const last = getPrev(this);
|
|
164
|
-
splice(last, extract(prev, node));
|
|
165
|
-
return this;
|
|
166
|
-
}
|
|
167
|
-
clear() {
|
|
168
|
-
this.next = this;
|
|
169
|
-
return this;
|
|
170
|
-
}
|
|
171
|
-
remove(from, to = from) {
|
|
172
|
-
const prevFrom = from instanceof SList.SListPtr ? from.prev : getPrev(this, from),
|
|
173
|
-
nodeTo = to instanceof SList.SListPtr ? to.node : to;
|
|
174
|
-
extract(prevFrom, nodeTo);
|
|
175
|
-
return this;
|
|
176
|
-
}
|
|
177
|
-
extract(from, to) {
|
|
178
|
-
const prevFrom = from instanceof SList.SListPtr ? from.prev : getPrev(this, from),
|
|
179
|
-
nodeTo = to instanceof SList.SListPtr ? to.node : to;
|
|
180
|
-
return splice(new SList(), extract(prevFrom, nodeTo));
|
|
181
|
-
}
|
|
182
|
-
reverse() {
|
|
183
|
-
let prev = this,
|
|
184
|
-
current = prev.next;
|
|
185
|
-
while (current !== this) {
|
|
186
|
-
const next = current.next;
|
|
187
|
-
current.next = prev;
|
|
188
|
-
prev = current;
|
|
189
|
-
current = next;
|
|
190
|
-
}
|
|
191
|
-
this.next = prev;
|
|
192
|
-
return this;
|
|
193
|
-
}
|
|
194
|
-
sort(compareFn) {
|
|
195
|
-
let current = this.next;
|
|
196
|
-
for (const value of Array.from(this).sort(compareFn)) {
|
|
197
|
-
current.value = value;
|
|
198
|
-
current = current.next;
|
|
199
|
-
}
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// iterators
|
|
204
|
-
|
|
205
|
-
[Symbol.iterator]() {
|
|
206
|
-
let current = this.next;
|
|
207
|
-
return {
|
|
208
|
-
next: () => {
|
|
209
|
-
if (current === this) return {
|
|
210
|
-
done: true
|
|
211
|
-
};
|
|
212
|
-
const node = current;
|
|
213
|
-
current = current.next;
|
|
214
|
-
return {
|
|
215
|
-
value: node.value
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
getIterable(from, to) {
|
|
221
|
-
return {
|
|
222
|
-
[Symbol.iterator]: () => {
|
|
223
|
-
let current = from instanceof SList.SListPtr && from.node || from || this.next;
|
|
224
|
-
const stop = to ? (to instanceof SList.SListPtr && to.node || to).next : this;
|
|
225
|
-
return {
|
|
226
|
-
next: () => {
|
|
227
|
-
if (current === stop) return {
|
|
228
|
-
done: true
|
|
229
|
-
};
|
|
230
|
-
const node = current;
|
|
231
|
-
current = current.next;
|
|
232
|
-
return {
|
|
233
|
-
value: node.value
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
getNodeIterable(from, to) {
|
|
241
|
-
return {
|
|
242
|
-
[Symbol.iterator]: () => {
|
|
243
|
-
let current = from instanceof SList.SListPtr && from.node || from || this.next;
|
|
244
|
-
const stop = to ? (to instanceof SList.SListPtr && to.node || to).next : this;
|
|
245
|
-
return {
|
|
246
|
-
next: () => {
|
|
247
|
-
if (current === stop) return {
|
|
248
|
-
done: true
|
|
249
|
-
};
|
|
250
|
-
const node = current;
|
|
251
|
-
current = current.next;
|
|
252
|
-
return {
|
|
253
|
-
value: node
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
getPtrIterable(from, to) {
|
|
261
|
-
return {
|
|
262
|
-
[Symbol.iterator]: () => {
|
|
263
|
-
let current = from instanceof SList.SListPtr ? from.clone() : from ? new SList.SListPtr(this, getPrev(this.head, from)) : this.getPtr();
|
|
264
|
-
const stop = to ? (to instanceof SList.SListPtr && to.node || to).next : this;
|
|
265
|
-
return {
|
|
266
|
-
next: () => {
|
|
267
|
-
if (current.node === stop) return {
|
|
268
|
-
done: true
|
|
269
|
-
};
|
|
270
|
-
const value = current.clone();
|
|
271
|
-
current.next();
|
|
272
|
-
return {
|
|
273
|
-
value
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// helpers
|
|
282
|
-
|
|
283
|
-
makeFrom(values) {
|
|
284
|
-
return SList.from(values);
|
|
285
|
-
}
|
|
286
|
-
pushValuesFront(values) {
|
|
287
|
-
for (const value of values) {
|
|
288
|
-
this.pushFront(value);
|
|
289
|
-
}
|
|
290
|
-
return this;
|
|
291
|
-
}
|
|
292
|
-
appendValuesFront(values) {
|
|
293
|
-
return this.appendFront(SList.from(values));
|
|
294
|
-
}
|
|
295
|
-
static from(values) {
|
|
296
|
-
const list = new SList();
|
|
297
|
-
let prev = list;
|
|
298
|
-
for (const value of values) {
|
|
299
|
-
const node = new SListValueNode(value);
|
|
300
|
-
prev.next = node;
|
|
301
|
-
prev = node;
|
|
302
|
-
}
|
|
303
|
-
prev.next = list;
|
|
304
|
-
return list;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
SList.pop = pop;
|
|
308
|
-
SList.extract = extract;
|
|
309
|
-
SList.splice = splice;
|
|
310
|
-
SList.getPrev = getPrev;
|
|
311
|
-
SList.getPrevPrev = getPrevPrev;
|
|
312
|
-
SList.Node = SListNode;
|
|
313
|
-
SList.ValueNode = SListValueNode;
|
|
314
|
-
SList.prototype.pop = SList.prototype.popFront;
|
|
315
|
-
SList.prototype.push = SList.prototype.pushFront;
|
|
316
|
-
SList.prototype.append = SList.prototype.appendBack;
|
|
317
|
-
SList.SListPtr = class SListPtr {
|
|
318
|
-
constructor(list, prev) {
|
|
319
|
-
this.list = list;
|
|
320
|
-
this.prev = prev || list;
|
|
321
|
-
}
|
|
322
|
-
get node() {
|
|
323
|
-
return this.prev.next;
|
|
324
|
-
}
|
|
325
|
-
get isHead() {
|
|
326
|
-
return this.prev.next === this.list;
|
|
327
|
-
}
|
|
328
|
-
next() {
|
|
329
|
-
this.prev = this.prev.next;
|
|
330
|
-
return this;
|
|
331
|
-
}
|
|
332
|
-
clone() {
|
|
333
|
-
return new SList.SListPtr(this.list, this.prev);
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
var _default = exports.default = SList;
|