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.
Files changed (86) hide show
  1. package/README.md +93 -407
  2. package/cjs/cache/cache-fifo.js +37 -0
  3. package/cjs/cache/cache-lfu.js +76 -0
  4. package/cjs/cache/cache-lru.js +100 -0
  5. package/cjs/cache/cache-random.js +77 -0
  6. package/cjs/cache/decorator.js +47 -0
  7. package/cjs/cache.js +28 -0
  8. package/cjs/ext-list.js +22 -0
  9. package/cjs/ext-slist.js +22 -0
  10. package/cjs/ext-value-list.js +22 -0
  11. package/cjs/ext-value-slist.js +22 -0
  12. package/cjs/{MinHeap.js → heap/min-heap.js} +77 -10
  13. package/cjs/heap.js +22 -0
  14. package/cjs/list/basics.js +88 -0
  15. package/cjs/list/core.js +305 -0
  16. package/cjs/list/ext-value.js +89 -0
  17. package/cjs/list/ext.js +356 -0
  18. package/cjs/list/nodes.js +240 -0
  19. package/cjs/list/ptr.js +61 -0
  20. package/cjs/list/value.js +100 -0
  21. package/cjs/list-helpers.js +91 -0
  22. package/cjs/list-utils.js +141 -0
  23. package/cjs/list.js +22 -0
  24. package/cjs/meta-utils.js +167 -0
  25. package/cjs/nt-utils.js +132 -0
  26. package/cjs/queue.js +58 -0
  27. package/cjs/slist/basics.js +71 -0
  28. package/cjs/slist/core.js +362 -0
  29. package/cjs/slist/ext-value.js +83 -0
  30. package/cjs/slist/ext.js +336 -0
  31. package/cjs/slist/nodes.js +276 -0
  32. package/cjs/slist/ptr.js +87 -0
  33. package/cjs/slist/value.js +91 -0
  34. package/cjs/slist.js +22 -0
  35. package/cjs/stack.js +55 -0
  36. package/cjs/value-list.js +22 -0
  37. package/cjs/value-slist.js +22 -0
  38. package/package.json +10 -8
  39. package/src/cache/cache-fifo.js +27 -0
  40. package/src/cache/cache-lfu.js +63 -0
  41. package/src/cache/cache-lru.js +87 -0
  42. package/src/cache/cache-random.js +73 -0
  43. package/src/cache/decorator.js +45 -0
  44. package/src/cache.js +9 -0
  45. package/src/ext-list.js +6 -0
  46. package/src/ext-slist.js +6 -0
  47. package/src/ext-value-list.js +6 -0
  48. package/src/ext-value-slist.js +6 -0
  49. package/src/{MinHeap.js → heap/min-heap.js} +91 -9
  50. package/src/heap.js +6 -0
  51. package/src/list/basics.js +64 -0
  52. package/src/list/core.js +314 -0
  53. package/src/list/ext-value.js +81 -0
  54. package/src/list/ext.js +370 -0
  55. package/src/list/nodes.js +262 -0
  56. package/src/list/ptr.js +58 -0
  57. package/src/list/value.js +88 -0
  58. package/src/list-helpers.js +80 -0
  59. package/src/list-utils.js +140 -0
  60. package/src/list.js +6 -0
  61. package/src/meta-utils.js +147 -0
  62. package/src/nt-utils.js +85 -0
  63. package/src/queue.js +52 -0
  64. package/src/slist/basics.js +47 -0
  65. package/src/slist/core.js +364 -0
  66. package/src/slist/ext-value.js +74 -0
  67. package/src/slist/ext.js +331 -0
  68. package/src/slist/nodes.js +290 -0
  69. package/src/slist/ptr.js +77 -0
  70. package/src/slist/value.js +75 -0
  71. package/src/slist.js +6 -0
  72. package/src/stack.js +52 -0
  73. package/src/value-list.js +6 -0
  74. package/src/value-slist.js +6 -0
  75. package/cjs/Cache.js +0 -70
  76. package/cjs/List.js +0 -291
  77. package/cjs/ListHead.js +0 -308
  78. package/cjs/SList.js +0 -336
  79. package/cjs/SListHead.js +0 -363
  80. package/cjs/utils.js +0 -43
  81. package/src/Cache.js +0 -61
  82. package/src/List.js +0 -303
  83. package/src/ListHead.js +0 -304
  84. package/src/SList.js +0 -329
  85. package/src/SListHead.js +0 -353
  86. 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;