atomic-fns 0.3.1 → 0.3.3-beta
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/.esdoc.json +2 -2
- package/README.md +62 -13
- package/core/collections/BTree.d.ts +229 -0
- package/core/collections/BTree.js +1165 -0
- package/core/collections/BTree.ts +1340 -0
- package/core/collections/Heap.d.ts +69 -0
- package/core/collections/Heap.js +181 -0
- package/core/collections/Heap.ts +189 -0
- package/core/collections/LRUCache.d.ts +152 -0
- package/core/collections/LRUCache.js +409 -0
- package/core/collections/LRUCache.ts +486 -0
- package/core/collections/SortedMap.d.ts +92 -0
- package/core/collections/SortedMap.js +130 -0
- package/core/collections/SortedMap.ts +146 -0
- package/core/collections/SortedSet.d.ts +69 -0
- package/core/collections/SortedSet.js +99 -0
- package/core/collections/SortedSet.ts +110 -0
- package/core/collections/SortedTree.d.ts +103 -0
- package/core/collections/SortedTree.js +141 -0
- package/core/collections/SortedTree.ts +160 -0
- package/core/collections/SplayTree.d.ts +105 -0
- package/core/collections/SplayTree.js +338 -0
- package/core/collections/SplayTree.ts +354 -0
- package/core/collections/abc.d.ts +152 -0
- package/core/collections/abc.js +39 -0
- package/core/collections/abc.ts +176 -0
- package/core/collections/deque.d.ts +110 -0
- package/core/collections/deque.js +285 -0
- package/core/collections/deque.ts +329 -0
- package/core/collections/frozenset.d.ts +19 -0
- package/core/collections/frozenset.js +33 -0
- package/core/collections/frozenset.ts +37 -0
- package/{src → core}/collections/index.d.ts +43 -162
- package/{src → core}/collections/index.js +59 -165
- package/{src → core}/collections/index.ts +64 -226
- package/core/collections/test.html +10 -0
- package/core/collections/typedArrays.d.ts +31 -0
- package/core/collections/typedArrays.js +143 -0
- package/core/collections/typedArrays.ts +163 -0
- package/{src → core}/functools/index.d.ts +2 -2
- package/{src → core}/functools/index.js +2 -2
- package/{src → core}/functools/index.ts +2 -2
- package/{src → core}/globals/index.d.ts +2 -7
- package/{src → core}/globals/index.js +5 -2
- package/{src → core}/globals/index.ts +6 -9
- package/{src → core}/index.d.ts +0 -1
- package/{src → core}/index.js +0 -1
- package/{src → core}/index.ts +0 -1
- package/{src → core}/itertools/index.d.ts +9 -7
- package/{src → core}/itertools/index.js +25 -9
- package/{src → core}/itertools/index.ts +39 -16
- package/{src → core}/math/index.d.ts +0 -0
- package/{src → core}/math/index.js +0 -0
- package/{src → core}/math/index.ts +0 -0
- package/core/operators/index.d.ts +148 -0
- package/core/operators/index.js +271 -0
- package/core/operators/index.ts +282 -0
- package/{src → core}/random/index.d.ts +0 -0
- package/{src → core}/random/index.js +0 -0
- package/{src → core}/random/index.ts +0 -0
- package/package.json +6 -6
- package/tests/BTree.spec.ts +143 -0
- package/tests/Cache.spec.ts +161 -0
- package/tests/Heap.spec.ts +66 -0
- package/tests/SortedMap.spec.ts +144 -0
- package/tests/SortedSet.spec.ts +84 -0
- package/tests/SortedTree.spec.ts +164 -0
- package/tests/SplayTree.spec.ts +121 -0
- package/tests/collections.spec.ts +1 -1
- package/tests/deque.spec.ts +107 -0
- package/tests/globals.spec.ts +2 -2
- package/tests/itertools.spec.ts +2 -2
- package/tests/math.spec.ts +1 -1
- package/tests/operators.spec.ts +5 -5
- package/tests/random.spec.ts +10 -10
- package/tsconfig.json +10 -10
- package/tsconfig.node.json +2 -2
- package/tsconfig.xo.json +2 -2
- package/src/datetime/index.d.ts +0 -6
- package/src/datetime/index.js +0 -6
- package/src/datetime/index.ts +0 -7
- package/src/operators/index.d.ts +0 -31
- package/src/operators/index.js +0 -171
- package/src/operators/index.ts +0 -175
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Iteratee } from '../globals/index.js';
|
|
2
|
+
import { Sequence } from './abc.js';
|
|
3
|
+
/**
|
|
4
|
+
* Fixed capacity double-ended queue implemented as ring deque.
|
|
5
|
+
*
|
|
6
|
+
* @constructor
|
|
7
|
+
*/
|
|
8
|
+
export declare class Deque<T> extends Sequence<T> {
|
|
9
|
+
items: T[];
|
|
10
|
+
start: number;
|
|
11
|
+
count: number;
|
|
12
|
+
capacity: number;
|
|
13
|
+
ArrayClass: any;
|
|
14
|
+
constructor(ArrayClass?: T[], capacity?: number);
|
|
15
|
+
get size(): number;
|
|
16
|
+
/**
|
|
17
|
+
* Method used to clear the structure.
|
|
18
|
+
*
|
|
19
|
+
* @return {undefined}
|
|
20
|
+
*/
|
|
21
|
+
clear(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Alias of {@link Deque.append}
|
|
24
|
+
*
|
|
25
|
+
* @param {any} item - Item to append.
|
|
26
|
+
* @return {number} - Returns the new size of the deque.
|
|
27
|
+
*/
|
|
28
|
+
add(item: any): number;
|
|
29
|
+
/**
|
|
30
|
+
* Method used to append a value to the deque.
|
|
31
|
+
*
|
|
32
|
+
* @param {any} item - Item to append.
|
|
33
|
+
* @return {number} - Returns the new size of the deque.
|
|
34
|
+
*/
|
|
35
|
+
append(item: any): number;
|
|
36
|
+
/**
|
|
37
|
+
* Method used to prepend a value to the deque.
|
|
38
|
+
*
|
|
39
|
+
* @param {any} item - Item to prepend.
|
|
40
|
+
* @return {number} - Returns the new size of the deque.
|
|
41
|
+
*/
|
|
42
|
+
appendleft(item: any): number;
|
|
43
|
+
/**
|
|
44
|
+
* Method used to pop the deque.
|
|
45
|
+
*
|
|
46
|
+
* @return {any} - Returns the popped item.
|
|
47
|
+
*/
|
|
48
|
+
pop(): T | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Alias of {@link Deque.pop}
|
|
51
|
+
*/
|
|
52
|
+
remove(): T | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Method used to shift the deque.
|
|
55
|
+
*
|
|
56
|
+
* @return {any} - Returns the shifted item.
|
|
57
|
+
*/
|
|
58
|
+
popleft(): T | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Method used to peek the first value of the deque.
|
|
61
|
+
*
|
|
62
|
+
* @return {any}
|
|
63
|
+
*/
|
|
64
|
+
first(): T | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Method used to get the desired value of the deque.
|
|
67
|
+
*
|
|
68
|
+
* @param {number} index
|
|
69
|
+
* @return {any}
|
|
70
|
+
*/
|
|
71
|
+
get(index: any): T | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Update the value at a given `index`.
|
|
74
|
+
* @param index The given index
|
|
75
|
+
* @param value The new value to set at `index`.
|
|
76
|
+
*/
|
|
77
|
+
set(index: number, value: T): void;
|
|
78
|
+
contains(x: any): boolean;
|
|
79
|
+
find(iteratee: Iteratee<T>): T | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Method used to iterate over the deque.
|
|
82
|
+
*
|
|
83
|
+
* @param {function} iteratee - Function to call for each item.
|
|
84
|
+
* @param {object} scope - Optional scope.
|
|
85
|
+
* @return {undefined}
|
|
86
|
+
*/
|
|
87
|
+
forEach(iteratee: any): void;
|
|
88
|
+
reversed(): any;
|
|
89
|
+
/**
|
|
90
|
+
* Method used to convert the deque to a JavaScript array.
|
|
91
|
+
*
|
|
92
|
+
* @return {array}
|
|
93
|
+
*/
|
|
94
|
+
toArray(): any;
|
|
95
|
+
/**
|
|
96
|
+
* Method used to create an iterator over the deque's values.
|
|
97
|
+
*
|
|
98
|
+
* @return {Iterator}
|
|
99
|
+
*/
|
|
100
|
+
values(): Iterable<T>;
|
|
101
|
+
keys(): Iterable<T>;
|
|
102
|
+
/**
|
|
103
|
+
* Method used to create an iterator over the deque's entries.
|
|
104
|
+
*
|
|
105
|
+
* @return {Iterator}
|
|
106
|
+
*/
|
|
107
|
+
entries(): Iterator<[number, T], any, undefined> & Iterable<[number, T]>;
|
|
108
|
+
[Symbol.iterator](): Iterable<T>;
|
|
109
|
+
inspect(): any;
|
|
110
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { KeyError, ValueError } from '../globals/index.js';
|
|
2
|
+
import { IterableIterator } from '../itertools/index.js';
|
|
3
|
+
import { eq } from '../operators/index.js';
|
|
4
|
+
import { Sequence } from './abc.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fixed capacity double-ended queue implemented as ring deque.
|
|
7
|
+
*
|
|
8
|
+
* @constructor
|
|
9
|
+
*/
|
|
10
|
+
export class Deque extends Sequence {
|
|
11
|
+
items;
|
|
12
|
+
start = 0;
|
|
13
|
+
count = 0;
|
|
14
|
+
capacity;
|
|
15
|
+
ArrayClass;
|
|
16
|
+
constructor(ArrayClass = [], capacity = 1024) {
|
|
17
|
+
super();
|
|
18
|
+
if (typeof capacity !== 'number' || capacity <= 0)
|
|
19
|
+
throw new ValueError(`Deque capacity should be a positive integer.`);
|
|
20
|
+
this.ArrayClass = ArrayClass.constructor;
|
|
21
|
+
this.capacity = capacity;
|
|
22
|
+
this.items = new this.ArrayClass(ArrayClass.length || this.capacity);
|
|
23
|
+
this.clear();
|
|
24
|
+
if (ArrayClass.length) {
|
|
25
|
+
for (const item of ArrayClass) {
|
|
26
|
+
this.append(item);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
get size() {
|
|
31
|
+
return this.count;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Method used to clear the structure.
|
|
35
|
+
*
|
|
36
|
+
* @return {undefined}
|
|
37
|
+
*/
|
|
38
|
+
clear() {
|
|
39
|
+
// Properties
|
|
40
|
+
this.start = 0;
|
|
41
|
+
this.count = 0;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Alias of {@link Deque.append}
|
|
45
|
+
*
|
|
46
|
+
* @param {any} item - Item to append.
|
|
47
|
+
* @return {number} - Returns the new size of the deque.
|
|
48
|
+
*/
|
|
49
|
+
add(item) {
|
|
50
|
+
return this.append(item);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Method used to append a value to the deque.
|
|
54
|
+
*
|
|
55
|
+
* @param {any} item - Item to append.
|
|
56
|
+
* @return {number} - Returns the new size of the deque.
|
|
57
|
+
*/
|
|
58
|
+
append(item) {
|
|
59
|
+
if (this.count === this.capacity)
|
|
60
|
+
this.popleft();
|
|
61
|
+
const index = (this.start + this.count) % this.capacity;
|
|
62
|
+
this.items[index] = item;
|
|
63
|
+
return ++this.count;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Method used to prepend a value to the deque.
|
|
67
|
+
*
|
|
68
|
+
* @param {any} item - Item to prepend.
|
|
69
|
+
* @return {number} - Returns the new size of the deque.
|
|
70
|
+
*/
|
|
71
|
+
appendleft(item) {
|
|
72
|
+
if (this.count === this.capacity)
|
|
73
|
+
this.pop();
|
|
74
|
+
let index = this.start - 1;
|
|
75
|
+
if (this.start === 0)
|
|
76
|
+
index = this.capacity - 1;
|
|
77
|
+
this.items[index] = item;
|
|
78
|
+
this.start = index;
|
|
79
|
+
return ++this.count;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Method used to pop the deque.
|
|
83
|
+
*
|
|
84
|
+
* @return {any} - Returns the popped item.
|
|
85
|
+
*/
|
|
86
|
+
pop() {
|
|
87
|
+
if (this.count === 0)
|
|
88
|
+
return;
|
|
89
|
+
const index = (this.start + this.count - 1) % this.capacity;
|
|
90
|
+
this.count--;
|
|
91
|
+
return this.items[index];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Alias of {@link Deque.pop}
|
|
95
|
+
*/
|
|
96
|
+
remove() {
|
|
97
|
+
return this.pop();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Method used to shift the deque.
|
|
101
|
+
*
|
|
102
|
+
* @return {any} - Returns the shifted item.
|
|
103
|
+
*/
|
|
104
|
+
popleft() {
|
|
105
|
+
if (this.count === 0)
|
|
106
|
+
return;
|
|
107
|
+
const index = this.start;
|
|
108
|
+
this.count--;
|
|
109
|
+
this.start++;
|
|
110
|
+
if (this.start === this.capacity)
|
|
111
|
+
this.start = 0;
|
|
112
|
+
return this.items[index];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Method used to peek the first value of the deque.
|
|
116
|
+
*
|
|
117
|
+
* @return {any}
|
|
118
|
+
*/
|
|
119
|
+
first() {
|
|
120
|
+
if (this.count === 0)
|
|
121
|
+
return;
|
|
122
|
+
return this.items[this.start];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Method used to get the desired value of the deque.
|
|
126
|
+
*
|
|
127
|
+
* @param {number} index
|
|
128
|
+
* @return {any}
|
|
129
|
+
*/
|
|
130
|
+
get(index) {
|
|
131
|
+
if (this.count === 0)
|
|
132
|
+
return;
|
|
133
|
+
index = this.start + index;
|
|
134
|
+
if (index < 0)
|
|
135
|
+
index += this.count;
|
|
136
|
+
if (index > this.capacity)
|
|
137
|
+
index -= this.capacity;
|
|
138
|
+
return this.items[index];
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Update the value at a given `index`.
|
|
142
|
+
* @param index The given index
|
|
143
|
+
* @param value The new value to set at `index`.
|
|
144
|
+
*/
|
|
145
|
+
set(index, value) {
|
|
146
|
+
if (index < 0)
|
|
147
|
+
index += this.count;
|
|
148
|
+
if (index > this.count)
|
|
149
|
+
throw new KeyError(`Invalid index: ${index} not in Deque.`);
|
|
150
|
+
this.items[index] = value;
|
|
151
|
+
}
|
|
152
|
+
contains(x) {
|
|
153
|
+
for (const value of this.values()) {
|
|
154
|
+
if (eq(x, value))
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
find(iteratee) {
|
|
160
|
+
for (const [key, value] of this.entries()) {
|
|
161
|
+
if (iteratee(value, key, this))
|
|
162
|
+
return value;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Method used to iterate over the deque.
|
|
167
|
+
*
|
|
168
|
+
* @param {function} iteratee - Function to call for each item.
|
|
169
|
+
* @param {object} scope - Optional scope.
|
|
170
|
+
* @return {undefined}
|
|
171
|
+
*/
|
|
172
|
+
forEach(iteratee) {
|
|
173
|
+
const c = this.capacity;
|
|
174
|
+
const l = this.count;
|
|
175
|
+
let i = this.start;
|
|
176
|
+
let j = 0;
|
|
177
|
+
while (j < l) {
|
|
178
|
+
iteratee(this.items[i], j, this);
|
|
179
|
+
i++;
|
|
180
|
+
j++;
|
|
181
|
+
if (i === c)
|
|
182
|
+
i = 0;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
reversed() {
|
|
186
|
+
return this.toArray().reverse();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Method used to convert the deque to a JavaScript array.
|
|
190
|
+
*
|
|
191
|
+
* @return {array}
|
|
192
|
+
*/
|
|
193
|
+
toArray() {
|
|
194
|
+
// Optimization
|
|
195
|
+
const offset = this.start + this.count;
|
|
196
|
+
if (offset < this.capacity)
|
|
197
|
+
return this.items.slice(this.start, offset);
|
|
198
|
+
const array = new this.ArrayClass(this.count);
|
|
199
|
+
const c = this.capacity;
|
|
200
|
+
const l = this.count;
|
|
201
|
+
let i = this.start;
|
|
202
|
+
let j = 0;
|
|
203
|
+
while (j < l) {
|
|
204
|
+
array[j] = this.items[i];
|
|
205
|
+
i++;
|
|
206
|
+
j++;
|
|
207
|
+
if (i === c)
|
|
208
|
+
i = 0;
|
|
209
|
+
}
|
|
210
|
+
return array;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Method used to create an iterator over the deque's values.
|
|
214
|
+
*
|
|
215
|
+
* @return {Iterator}
|
|
216
|
+
*/
|
|
217
|
+
values() {
|
|
218
|
+
const items = this.items;
|
|
219
|
+
const c = this.capacity;
|
|
220
|
+
const l = this.count;
|
|
221
|
+
let i = this.start;
|
|
222
|
+
let j = 0;
|
|
223
|
+
return IterableIterator(() => {
|
|
224
|
+
if (j >= l)
|
|
225
|
+
return {
|
|
226
|
+
done: true
|
|
227
|
+
};
|
|
228
|
+
const value = items[i];
|
|
229
|
+
i++;
|
|
230
|
+
j++;
|
|
231
|
+
if (i === c)
|
|
232
|
+
i = 0;
|
|
233
|
+
return {
|
|
234
|
+
value,
|
|
235
|
+
done: false
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
keys() {
|
|
240
|
+
return this.values();
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Method used to create an iterator over the deque's entries.
|
|
244
|
+
*
|
|
245
|
+
* @return {Iterator}
|
|
246
|
+
*/
|
|
247
|
+
entries() {
|
|
248
|
+
const items = this.items;
|
|
249
|
+
const c = this.capacity;
|
|
250
|
+
const l = this.count;
|
|
251
|
+
let i = this.start;
|
|
252
|
+
let j = 0;
|
|
253
|
+
return IterableIterator(() => {
|
|
254
|
+
if (j >= l)
|
|
255
|
+
return {
|
|
256
|
+
done: true
|
|
257
|
+
};
|
|
258
|
+
const value = items[i];
|
|
259
|
+
i++;
|
|
260
|
+
if (i === c)
|
|
261
|
+
i = 0;
|
|
262
|
+
return {
|
|
263
|
+
value: [j++, value],
|
|
264
|
+
done: false
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
[Symbol.iterator]() {
|
|
269
|
+
return this.values();
|
|
270
|
+
}
|
|
271
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
272
|
+
return this.inspect();
|
|
273
|
+
}
|
|
274
|
+
inspect() {
|
|
275
|
+
const array = this.toArray();
|
|
276
|
+
array.type = this.ArrayClass.name;
|
|
277
|
+
array.capacity = this.capacity;
|
|
278
|
+
// Trick so that node displays the name of the constructor
|
|
279
|
+
Object.defineProperty(array, 'constructor', {
|
|
280
|
+
value: Deque,
|
|
281
|
+
enumerable: false
|
|
282
|
+
});
|
|
283
|
+
return array;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { Iteratee, KeyError, ValueError } from '../globals/index.js'
|
|
2
|
+
import { IterableIterator } from '../itertools/index.js'
|
|
3
|
+
import { eq } from '../operators/index.js'
|
|
4
|
+
import { Sequence } from './abc.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Fixed capacity double-ended queue implemented as ring deque.
|
|
8
|
+
*
|
|
9
|
+
* @constructor
|
|
10
|
+
*/
|
|
11
|
+
export class Deque<T> extends Sequence<T> {
|
|
12
|
+
items: T[]
|
|
13
|
+
start: number = 0
|
|
14
|
+
count: number = 0
|
|
15
|
+
capacity: number
|
|
16
|
+
ArrayClass: any
|
|
17
|
+
|
|
18
|
+
constructor(ArrayClass = [] as T[], capacity = 1024) {
|
|
19
|
+
super()
|
|
20
|
+
if (typeof capacity !== 'number' || capacity <= 0)
|
|
21
|
+
throw new ValueError(`Deque capacity should be a positive integer.`)
|
|
22
|
+
|
|
23
|
+
this.ArrayClass = ArrayClass.constructor
|
|
24
|
+
this.capacity = capacity
|
|
25
|
+
this.items = new this.ArrayClass(ArrayClass.length || this.capacity)
|
|
26
|
+
this.clear()
|
|
27
|
+
if (ArrayClass.length) {
|
|
28
|
+
for (const item of ArrayClass) {
|
|
29
|
+
this.append(item)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get size() {
|
|
35
|
+
return this.count
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Method used to clear the structure.
|
|
40
|
+
*
|
|
41
|
+
* @return {undefined}
|
|
42
|
+
*/
|
|
43
|
+
clear() {
|
|
44
|
+
// Properties
|
|
45
|
+
this.start = 0
|
|
46
|
+
this.count = 0
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Alias of {@link Deque.append}
|
|
51
|
+
*
|
|
52
|
+
* @param {any} item - Item to append.
|
|
53
|
+
* @return {number} - Returns the new size of the deque.
|
|
54
|
+
*/
|
|
55
|
+
add(item) {
|
|
56
|
+
return this.append(item)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Method used to append a value to the deque.
|
|
61
|
+
*
|
|
62
|
+
* @param {any} item - Item to append.
|
|
63
|
+
* @return {number} - Returns the new size of the deque.
|
|
64
|
+
*/
|
|
65
|
+
append(item) {
|
|
66
|
+
if (this.count === this.capacity) this.popleft()
|
|
67
|
+
|
|
68
|
+
const index = (this.start + this.count) % this.capacity
|
|
69
|
+
|
|
70
|
+
this.items[index] = item
|
|
71
|
+
|
|
72
|
+
return ++this.count
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Method used to prepend a value to the deque.
|
|
77
|
+
*
|
|
78
|
+
* @param {any} item - Item to prepend.
|
|
79
|
+
* @return {number} - Returns the new size of the deque.
|
|
80
|
+
*/
|
|
81
|
+
appendleft(item) {
|
|
82
|
+
if (this.count === this.capacity) this.pop()
|
|
83
|
+
|
|
84
|
+
let index = this.start - 1
|
|
85
|
+
|
|
86
|
+
if (this.start === 0) index = this.capacity - 1
|
|
87
|
+
|
|
88
|
+
this.items[index] = item
|
|
89
|
+
this.start = index
|
|
90
|
+
|
|
91
|
+
return ++this.count
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Method used to pop the deque.
|
|
96
|
+
*
|
|
97
|
+
* @return {any} - Returns the popped item.
|
|
98
|
+
*/
|
|
99
|
+
pop() {
|
|
100
|
+
if (this.count === 0) return
|
|
101
|
+
|
|
102
|
+
const index = (this.start + this.count - 1) % this.capacity
|
|
103
|
+
|
|
104
|
+
this.count--
|
|
105
|
+
|
|
106
|
+
return this.items[index]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Alias of {@link Deque.pop}
|
|
111
|
+
*/
|
|
112
|
+
remove() {
|
|
113
|
+
return this.pop()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Method used to shift the deque.
|
|
118
|
+
*
|
|
119
|
+
* @return {any} - Returns the shifted item.
|
|
120
|
+
*/
|
|
121
|
+
popleft() {
|
|
122
|
+
if (this.count === 0) return
|
|
123
|
+
|
|
124
|
+
const index = this.start
|
|
125
|
+
|
|
126
|
+
this.count--
|
|
127
|
+
this.start++
|
|
128
|
+
|
|
129
|
+
if (this.start === this.capacity) this.start = 0
|
|
130
|
+
|
|
131
|
+
return this.items[index]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Method used to peek the first value of the deque.
|
|
136
|
+
*
|
|
137
|
+
* @return {any}
|
|
138
|
+
*/
|
|
139
|
+
first() {
|
|
140
|
+
if (this.count === 0) return
|
|
141
|
+
|
|
142
|
+
return this.items[this.start]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Method used to get the desired value of the deque.
|
|
147
|
+
*
|
|
148
|
+
* @param {number} index
|
|
149
|
+
* @return {any}
|
|
150
|
+
*/
|
|
151
|
+
get(index) {
|
|
152
|
+
if (this.count === 0) return
|
|
153
|
+
|
|
154
|
+
index = this.start + index
|
|
155
|
+
if (index < 0) index += this.count
|
|
156
|
+
|
|
157
|
+
if (index > this.capacity) index -= this.capacity
|
|
158
|
+
|
|
159
|
+
return this.items[index]
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Update the value at a given `index`.
|
|
164
|
+
* @param index The given index
|
|
165
|
+
* @param value The new value to set at `index`.
|
|
166
|
+
*/
|
|
167
|
+
set(index: number, value: T) {
|
|
168
|
+
if (index < 0) index += this.count
|
|
169
|
+
if (index > this.count) throw new KeyError(`Invalid index: ${index} not in Deque.`)
|
|
170
|
+
this.items[index] = value
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
contains(x) {
|
|
174
|
+
for (const value of this.values()) {
|
|
175
|
+
if (eq(x, value)) return true
|
|
176
|
+
}
|
|
177
|
+
return false
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
find(iteratee: Iteratee<T>) {
|
|
181
|
+
for (const [key, value] of this.entries()) {
|
|
182
|
+
if (iteratee(value, key, this)) return value
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Method used to iterate over the deque.
|
|
188
|
+
*
|
|
189
|
+
* @param {function} iteratee - Function to call for each item.
|
|
190
|
+
* @param {object} scope - Optional scope.
|
|
191
|
+
* @return {undefined}
|
|
192
|
+
*/
|
|
193
|
+
forEach(iteratee) {
|
|
194
|
+
const c = this.capacity
|
|
195
|
+
const l = this.count
|
|
196
|
+
let i = this.start
|
|
197
|
+
let j = 0
|
|
198
|
+
|
|
199
|
+
while (j < l) {
|
|
200
|
+
iteratee(this.items[i], j, this)
|
|
201
|
+
i++
|
|
202
|
+
j++
|
|
203
|
+
|
|
204
|
+
if (i === c) i = 0
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
reversed() {
|
|
209
|
+
return this.toArray().reverse()
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Method used to convert the deque to a JavaScript array.
|
|
214
|
+
*
|
|
215
|
+
* @return {array}
|
|
216
|
+
*/
|
|
217
|
+
toArray() {
|
|
218
|
+
// Optimization
|
|
219
|
+
const offset = this.start + this.count
|
|
220
|
+
|
|
221
|
+
if (offset < this.capacity) return this.items.slice(this.start, offset)
|
|
222
|
+
|
|
223
|
+
const array = new this.ArrayClass(this.count)
|
|
224
|
+
const c = this.capacity
|
|
225
|
+
const l = this.count
|
|
226
|
+
let i = this.start
|
|
227
|
+
let j = 0
|
|
228
|
+
|
|
229
|
+
while (j < l) {
|
|
230
|
+
array[j] = this.items[i]
|
|
231
|
+
i++
|
|
232
|
+
j++
|
|
233
|
+
|
|
234
|
+
if (i === c) i = 0
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return array
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Method used to create an iterator over the deque's values.
|
|
242
|
+
*
|
|
243
|
+
* @return {Iterator}
|
|
244
|
+
*/
|
|
245
|
+
values(): Iterable<T> {
|
|
246
|
+
const items = this.items
|
|
247
|
+
const c = this.capacity
|
|
248
|
+
const l = this.count
|
|
249
|
+
let i = this.start
|
|
250
|
+
let j = 0
|
|
251
|
+
|
|
252
|
+
return IterableIterator(() => {
|
|
253
|
+
if (j >= l)
|
|
254
|
+
return {
|
|
255
|
+
done: true
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const value = items[i]
|
|
259
|
+
|
|
260
|
+
i++
|
|
261
|
+
j++
|
|
262
|
+
|
|
263
|
+
if (i === c) i = 0
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
value,
|
|
267
|
+
done: false
|
|
268
|
+
}
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
keys() {
|
|
273
|
+
return this.values()
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Method used to create an iterator over the deque's entries.
|
|
278
|
+
*
|
|
279
|
+
* @return {Iterator}
|
|
280
|
+
*/
|
|
281
|
+
entries() {
|
|
282
|
+
const items = this.items
|
|
283
|
+
const c = this.capacity
|
|
284
|
+
const l = this.count
|
|
285
|
+
let i = this.start
|
|
286
|
+
let j = 0
|
|
287
|
+
|
|
288
|
+
return IterableIterator<[number, T]>(() => {
|
|
289
|
+
if (j >= l)
|
|
290
|
+
return {
|
|
291
|
+
done: true
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const value = items[i]
|
|
295
|
+
|
|
296
|
+
i++
|
|
297
|
+
|
|
298
|
+
if (i === c) i = 0
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
value: [j++, value],
|
|
302
|
+
done: false
|
|
303
|
+
}
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
[Symbol.iterator]() {
|
|
308
|
+
return this.values()
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
312
|
+
return this.inspect()
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
inspect() {
|
|
316
|
+
const array = this.toArray()
|
|
317
|
+
|
|
318
|
+
array.type = this.ArrayClass.name
|
|
319
|
+
array.capacity = this.capacity
|
|
320
|
+
|
|
321
|
+
// Trick so that node displays the name of the constructor
|
|
322
|
+
Object.defineProperty(array, 'constructor', {
|
|
323
|
+
value: Deque,
|
|
324
|
+
enumerable: false
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
return array
|
|
328
|
+
}
|
|
329
|
+
}
|