solists 0.3.0 → 1.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.
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DoublyLinkedList = void 0;
4
4
  const Node_1 = require("./Node");
5
5
  class DoublyLinkedList {
6
- constructor(rearrangeOnCreation = false, iterable = null) {
7
- this.head = null;
8
- this.tail = null;
9
- this.length = 0;
10
- this.rearrangeOnCreation = rearrangeOnCreation;
6
+ constructor(iterable = null, options = {}) {
7
+ var _a;
8
+ this._options = options;
9
+ this._head = null;
10
+ this._tail = null;
11
+ this._length = 0;
12
+ this._accessOnly = (_a = options.accessOnly) !== null && _a !== void 0 ? _a : true;
11
13
  if (iterable !== null) {
12
14
  this._extend(iterable);
13
15
  }
@@ -15,96 +17,94 @@ class DoublyLinkedList {
15
17
  [Symbol.iterator]() {
16
18
  return this._values();
17
19
  }
18
- // Public Array-like methods
20
+ // Public native Array methods
19
21
  at(index) {
20
22
  if (this.length === 0 || Math.abs(index) >= this.length) {
21
23
  return undefined;
22
24
  }
23
25
  index = this._toAbsoluteIndex(index, this.length);
24
26
  const targetNode = this._getNode(index);
25
- if (targetNode === null) {
26
- return undefined;
27
- }
28
27
  targetNode.count += 1;
29
28
  this._rearrange(targetNode);
30
29
  return targetNode.value;
31
30
  }
32
- concat(...values) {
33
- const { length: valuesLength } = values;
34
- const result = this.slice(0, this.length);
35
- for (let index = 0; index < valuesLength; index += 1) {
36
- const value = values[index];
37
- if (value instanceof DoublyLinkedList || Array.isArray(value)) {
38
- for (const currentValue of value.values()) {
39
- result.push(currentValue);
31
+ concat(...items) {
32
+ const result = this.slice();
33
+ for (const item of items) {
34
+ if (Array.isArray(item) || item instanceof DoublyLinkedList) {
35
+ for (const value of item) {
36
+ result.push(value);
40
37
  }
41
38
  }
42
39
  else {
43
- result.push(value);
40
+ result.push(item);
44
41
  }
45
42
  }
46
43
  return result;
47
44
  }
48
- copyWithin(target /* = 0 */, start /* = 0, end = @length */) {
45
+ copyWithin(target, start, end) {
46
+ const targetIndex = this._toAbsoluteIndex(target, this.length);
49
47
  const sourceStart = this._toAbsoluteIndex(start, this.length);
50
- const sourceEnd = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.length;
51
- const targetStart = this._toAbsoluteIndex(target, this.length);
52
- let count = Math.min((sourceEnd === this.length ? this.length : this._toAbsoluteIndex(sourceEnd, this.length)) - sourceStart, this.length - targetStart);
53
- const tempSrcLst = this.slice(0, this.length);
54
- const targetNodes = this._nodes(targetStart, targetStart + count);
55
- const sourceNodes = tempSrcLst._nodes(sourceStart, sourceStart + count);
56
- while (count > 0) {
57
- const targetCurrentNode = targetNodes.next();
58
- const sourceCurrentNode = sourceNodes.next();
59
- const targetCurrentValue = targetCurrentNode.value;
60
- const sourceCurrentValue = sourceCurrentNode.value;
61
- targetCurrentValue[1].value = sourceCurrentValue[1].value;
62
- count -= 1;
48
+ const sourceEnd = end === undefined ? this.length : this._toAbsoluteIndex(end, this.length);
49
+ let count = Math.min(sourceEnd - sourceStart, this.length - targetIndex);
50
+ if (count <= 0 || sourceStart === targetIndex)
51
+ return this;
52
+ if (sourceStart < targetIndex && targetIndex < sourceStart + count) {
53
+ let sourceNode = this._getNode(sourceStart + count - 1);
54
+ let targetNode = this._getNode(targetIndex + count - 1);
55
+ while (count > 0) {
56
+ targetNode.value = sourceNode.value;
57
+ sourceNode = sourceNode.prev;
58
+ targetNode = targetNode.prev;
59
+ count -= 1;
60
+ }
61
+ }
62
+ else {
63
+ let sourceNode = this._getNode(sourceStart);
64
+ let targetNode = this._getNode(targetIndex);
65
+ while (count > 0) {
66
+ targetNode.value = sourceNode.value;
67
+ sourceNode = sourceNode.next;
68
+ targetNode = targetNode.next;
69
+ count -= 1;
70
+ }
63
71
  }
64
72
  return this;
65
73
  }
66
74
  entries() {
67
75
  return this._entries();
68
76
  }
69
- // TODO: Support "thisArg" argument
70
- every(callbackFn) {
77
+ every(predicate, thisArg) {
78
+ this._aCallable(predicate);
71
79
  for (const [index, node] of this._nodes(0, this.length)) {
72
- if (!(callbackFn(node.value, index, this))) {
80
+ if (!predicate.call(thisArg, node.value, index, this)) {
73
81
  return false;
74
82
  }
75
83
  }
76
84
  return true;
77
85
  }
78
- fill(value) {
79
- let startIndex = undefined;
80
- if (arguments.length > 1) {
81
- startIndex = arguments[1];
82
- }
83
- startIndex = this._toAbsoluteIndex(startIndex, this.length);
84
- let endIndex = undefined;
85
- if (arguments.length > 2) {
86
- endIndex = arguments[2];
87
- }
88
- endIndex = (endIndex === undefined) ? this.length : this._toAbsoluteIndex(endIndex, this.length);
89
- for (const [/* index */ , node] of this._nodes(startIndex, endIndex)) {
86
+ fill(value, start, end) {
87
+ const startIndex = this._toAbsoluteIndex(start, this.length);
88
+ const endIndex = end === undefined ? this.length : this._toAbsoluteIndex(end, this.length);
89
+ for (const [, node] of this._nodes(startIndex, endIndex)) {
90
90
  node.value = value;
91
91
  }
92
92
  return this;
93
93
  }
94
- // TODO: Support "thisArg" argument
95
- filter(callbackFn) {
94
+ filter(predicate, thisArg) {
95
+ this._aCallable(predicate);
96
96
  const result = new DoublyLinkedList();
97
97
  for (const [index, node] of this._nodes(0, this.length)) {
98
- if (callbackFn(node.value, index, this)) {
98
+ if (predicate.call(thisArg, node.value, index, this)) {
99
99
  result.push(node.value);
100
100
  }
101
101
  }
102
102
  return result;
103
103
  }
104
- // TODO: Support "thisArg" argument
105
- find(callbackFn) {
104
+ find(predicate, thisArg) {
105
+ this._aCallable(predicate);
106
106
  for (const [index, node] of this._nodes(0, this.length)) {
107
- if (callbackFn(node.value, index, this)) {
107
+ if (predicate.call(thisArg, node.value, index, this)) {
108
108
  node.count += 1;
109
109
  this._rearrange(node);
110
110
  return node.value;
@@ -112,21 +112,21 @@ class DoublyLinkedList {
112
112
  }
113
113
  return undefined;
114
114
  }
115
- // TODO: Support "thisArg" argument
116
- findIndex(callbackFn) {
115
+ findIndex(predicate, thisArg) {
116
+ this._aCallable(predicate);
117
117
  for (const [index, node] of this._nodes(0, this.length)) {
118
- if (callbackFn(node.value, index, this)) {
118
+ if (predicate.call(thisArg, node.value, index, this)) {
119
119
  node.count += 1;
120
120
  const result = this._rearrange(node);
121
- return (result === undefined) ? index : result;
121
+ return result === undefined ? index : result;
122
122
  }
123
123
  }
124
124
  return -1;
125
125
  }
126
- // TODO: Support "thisArg" argument
127
- findLast(callbackFn) {
126
+ findLast(predicate, thisArg) {
127
+ this._aCallable(predicate);
128
128
  for (const [index, node] of this._nodesReverse(0, this.length)) {
129
- if (callbackFn(node.value, index, this)) {
129
+ if (predicate.call(thisArg, node.value, index, this)) {
130
130
  node.count += 1;
131
131
  this._rearrange(node);
132
132
  return node.value;
@@ -134,43 +134,56 @@ class DoublyLinkedList {
134
134
  }
135
135
  return undefined;
136
136
  }
137
- // TODO: Support "thisArg" argument
138
- findLastIndex(callbackFn) {
137
+ findLastIndex(predicate, thisArg) {
138
+ this._aCallable(predicate);
139
139
  for (const [index, node] of this._nodesReverse(0, this.length)) {
140
- if (callbackFn(node.value, index, this)) {
140
+ if (predicate.call(thisArg, node.value, index, this)) {
141
141
  node.count += 1;
142
142
  const result = this._rearrange(node);
143
- return (result === undefined) ? index : result;
143
+ return result === undefined ? index : result;
144
144
  }
145
145
  }
146
146
  return -1;
147
147
  }
148
- flat(depth = 1) {
149
- depth = this._toIntegerOrInfinity(depth);
150
- if (depth < 1) {
151
- return this.slice(0, this.length);
148
+ flat(depth) {
149
+ const d = depth === undefined ? 1 : this._toIntegerOrInfinity(depth);
150
+ if (d < 1) {
151
+ return this.slice();
152
+ }
153
+ const result = new DoublyLinkedList();
154
+ for (const [, node] of this._nodes(0, this.length)) {
155
+ const value = node.value;
156
+ if (Array.isArray(value) || value instanceof DoublyLinkedList) {
157
+ const flattened = value instanceof DoublyLinkedList
158
+ ? value.flat(d - 1)
159
+ : new DoublyLinkedList(value).flat(d - 1);
160
+ for (const item of flattened) {
161
+ result.push(item);
162
+ }
163
+ }
164
+ else {
165
+ result.push(value);
166
+ }
152
167
  }
153
- return this.reduce(function (flat, toFlatten) {
154
- return flat.concat(((toFlatten instanceof DoublyLinkedList) && (depth > 1)) ? toFlatten.flat(depth - 1) : toFlatten);
155
- }, new DoublyLinkedList());
168
+ return result;
156
169
  }
157
- // TODO: Support "thisArg" argument
158
- flatMap(callbackFn) {
159
- return this.map(callbackFn).flat();
170
+ flatMap(callback, thisArg) {
171
+ this._aCallable(callback);
172
+ return this.map(callback, thisArg).flat();
160
173
  }
161
- forEach(callbackFn) {
174
+ forEach(callbackfn, thisArg) {
175
+ this._aCallable(callbackfn);
162
176
  for (const [index, node] of this._nodes(0, this.length)) {
163
- callbackFn(node.value, index, this);
177
+ callbackfn.call(thisArg, node.value, index, this);
164
178
  }
165
- return undefined;
166
179
  }
167
- includes(searchedValue, fromIndex) {
180
+ includes(searchElement, fromIndex) {
168
181
  if (this.length === 0) {
169
182
  return false;
170
183
  }
171
- fromIndex = this._toAbsoluteIndex(fromIndex, this.length);
172
- for (const [/* index */ , node] of this._nodes(fromIndex, this.length)) {
173
- if (this._sameValueZero(node.value, searchedValue)) {
184
+ const startIndex = this._toAbsoluteIndex(fromIndex, this.length);
185
+ for (const [, node] of this._nodes(startIndex, this.length)) {
186
+ if (this._sameValueZero(node.value, searchElement)) {
174
187
  node.count += 1;
175
188
  this._rearrange(node);
176
189
  return true;
@@ -178,66 +191,62 @@ class DoublyLinkedList {
178
191
  }
179
192
  return false;
180
193
  }
181
- indexOf(searchedValue, fromIndex = 0) {
194
+ indexOf(searchElement, fromIndex) {
182
195
  if (this.length === 0) {
183
196
  return -1;
184
197
  }
185
- fromIndex = this._toAbsoluteIndex(fromIndex, this.length);
186
- for (const [index, node] of this._nodes(fromIndex, this.length)) {
187
- if (this._isStrictlyEqual(node.value, searchedValue)) {
198
+ const startIndex = this._toAbsoluteIndex(fromIndex !== null && fromIndex !== void 0 ? fromIndex : 0, this.length);
199
+ for (const [index, node] of this._nodes(startIndex, this.length)) {
200
+ if (this._isStrictlyEqual(node.value, searchElement)) {
188
201
  node.count += 1;
189
202
  const result = this._rearrange(node);
190
- return (result === undefined) ? index : result;
203
+ return result === undefined ? index : result;
191
204
  }
192
205
  }
193
206
  return -1;
194
207
  }
195
208
  join(separator) {
196
- let result = '';
197
209
  if (this.length === 0) {
198
- return result;
199
- }
200
- if (separator === undefined) {
201
- separator = ',';
210
+ return "";
202
211
  }
212
+ const sep = separator === undefined ? "," : String(separator);
213
+ let result = "";
203
214
  for (const [index, node] of this._nodes(0, this.length)) {
204
- const value = node.value == null ? "" : node.value;
205
- if (index !== this.length - 1) {
206
- result = result.concat(value) + separator;
207
- }
208
- else {
209
- result = result.concat(value);
210
- }
215
+ const value = node.value == null ? "" : String(node.value);
216
+ result += index === 0 ? value : sep + value;
211
217
  }
212
218
  return result;
213
219
  }
214
220
  keys() {
215
221
  return this._keys();
216
222
  }
217
- lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {
223
+ get length() {
224
+ return this._length;
225
+ }
226
+ lastIndexOf(searchElement, fromIndex) {
218
227
  if (this.length === 0) {
219
228
  return -1;
220
229
  }
221
- let fromIndex = this.length - 1;
222
- if (arguments.length > 1) {
223
- fromIndex = Math.min(fromIndex, this._toIntegerOrInfinity(arguments[1]));
224
- }
225
- if (fromIndex < 0) {
226
- fromIndex = this.length + fromIndex;
230
+ let startIndex = arguments.length > 1
231
+ ? Math.min(this._toIntegerOrInfinity(fromIndex), this.length - 1)
232
+ : this.length - 1;
233
+ if (startIndex < 0) {
234
+ startIndex = this.length + startIndex;
227
235
  }
228
- for (const [index, node] of this._nodesReverse(0, fromIndex + 1)) {
236
+ for (const [index, node] of this._nodesReverse(0, startIndex + 1)) {
229
237
  if (this._isStrictlyEqual(node.value, searchElement)) {
230
238
  node.count += 1;
231
239
  const result = this._rearrange(node);
232
- return (result === undefined) ? index : result;
240
+ return result === undefined ? index : result;
233
241
  }
234
242
  }
235
243
  return -1;
236
244
  }
237
- map(callbackFn) {
245
+ map(callbackfn, thisArg) {
246
+ this._aCallable(callbackfn);
238
247
  const result = new DoublyLinkedList();
239
248
  for (const [index, node] of this._nodes(0, this.length)) {
240
- result.push(callbackFn(node.value, index, this));
249
+ result.push(callbackfn.call(thisArg, node.value, index, this));
241
250
  }
242
251
  return result;
243
252
  }
@@ -245,78 +254,72 @@ class DoublyLinkedList {
245
254
  if (this.length === 0) {
246
255
  return undefined;
247
256
  }
248
- const value = this.tail.value;
257
+ const value = this._tail.value;
249
258
  if (this.length === 1) {
250
259
  this._removeLast();
251
260
  }
252
261
  else {
253
- this.tail = this.tail.prev;
254
- this.tail.next = null;
255
- this.length -= 1;
262
+ this._tail = this._tail.prev;
263
+ this._tail.next = null;
264
+ this._length -= 1;
256
265
  }
257
266
  return value;
258
267
  }
259
- push(...values) {
260
- const { length: valuesLength } = values;
261
- for (let index = 0; index < valuesLength; index += 1) {
262
- const newNode = new Node_1.Node(values[index]);
268
+ push(...items) {
269
+ for (const item of items) {
270
+ const newNode = new Node_1.Node(item);
263
271
  if (this.length === 0) {
264
272
  this._insertFirst(newNode);
265
273
  }
266
- else if (this.tail !== null) {
267
- this._insertAfter(this.tail, newNode);
268
- }
269
274
  else {
270
- continue;
275
+ this._insertAfter(this._tail, newNode);
271
276
  }
272
- if (this.rearrangeOnCreation) {
277
+ if (!this._accessOnly) {
273
278
  this._rearrange(newNode);
274
279
  }
275
280
  }
276
281
  return this.length;
277
282
  }
278
- reduce(callbackFn, initialValue) {
279
- if (!(this._isCallable(callbackFn))) {
280
- throw TypeError(this._tryToString(callbackFn) + ' is not a function');
281
- }
282
- if (this.length === 0 && arguments.length < 2) {
283
- throw TypeError('Reduce of empty list with no initial value');
283
+ reduce(callbackfn, initialValue) {
284
+ this._aCallable(callbackfn);
285
+ const hasInitial = arguments.length > 1;
286
+ if (this.length === 0 && !hasInitial) {
287
+ throw TypeError("Reduce of empty list with no initial value");
284
288
  }
285
- let accumulator = arguments.length > 1 ? initialValue : this.head.value;
289
+ let accumulator = hasInitial ? initialValue : this._head.value;
286
290
  for (const [index, node] of this._nodes(0, this.length)) {
287
- if (arguments.length > 1 || index > 0) {
288
- accumulator = callbackFn(accumulator, node.value, index, this);
291
+ if (hasInitial || index > 0) {
292
+ accumulator = callbackfn(accumulator, node.value, index, this);
289
293
  }
290
294
  }
291
295
  return accumulator;
292
296
  }
293
- reduceRight(callbackFn, initialValue) {
294
- if (!(this._isCallable(callbackFn))) {
295
- throw TypeError(this._tryToString(callbackFn) + ' is not a function');
296
- }
297
- if (this.length === 0 && arguments.length < 2) {
298
- throw TypeError('Reduce of empty list with no initial value');
297
+ reduceRight(callbackfn, initialValue) {
298
+ this._aCallable(callbackfn);
299
+ const hasInitial = arguments.length > 1;
300
+ if (this.length === 0 && !hasInitial) {
301
+ throw TypeError("Reduce of empty list with no initial value");
299
302
  }
300
- let accumulator = arguments.length > 1 ? initialValue : this.tail.value;
303
+ let accumulator = hasInitial ? initialValue : this._tail.value;
301
304
  for (const [index, node] of this._nodesReverse(0, this.length)) {
302
- if (index < this.length - 1) {
303
- accumulator = callbackFn(accumulator, node.value, index, this);
305
+ if (hasInitial || index < this.length - 1) {
306
+ accumulator = callbackfn(accumulator, node.value, index, this);
304
307
  }
305
308
  }
306
309
  return accumulator;
307
310
  }
308
311
  reverse() {
309
312
  if (this.length > 1) {
310
- let curr = this.head;
313
+ let curr = this._head;
311
314
  while (curr) {
312
315
  const next = curr.next;
313
316
  curr.next = curr.prev;
314
317
  curr.prev = next;
315
318
  if (curr.next === null) {
316
- this.tail = curr;
319
+ this._tail = curr;
317
320
  }
318
321
  else if (curr.prev === null) {
319
- this.head = curr;
322
+ this._head = curr;
320
323
  }
321
324
  curr = next;
322
325
  }
@@ -327,67 +330,66 @@ class DoublyLinkedList {
327
330
  if (this.length === 0) {
328
331
  return undefined;
329
332
  }
330
- const value = this.head.value;
333
+ const value = this._head.value;
331
334
  if (this.length === 1) {
332
335
  this._removeLast();
333
336
  }
334
337
  else {
335
- this.head = this.head.next;
336
- this.head.prev = null;
337
- this.length -= 1;
338
+ this._head = this._head.next;
339
+ this._head.prev = null;
340
+ this._length -= 1;
338
341
  }
339
342
  return value;
340
343
  }
341
- slice(startIndex, endIndex) {
344
+ slice(start, end) {
342
345
  const result = new DoublyLinkedList();
343
- if (startIndex === undefined) {
344
- startIndex = 0;
345
- }
346
- startIndex = this._toAbsoluteIndex(startIndex, this.length);
347
- endIndex = this._toAbsoluteIndex(endIndex === undefined ? this.length : endIndex, this.length);
348
- for (const [/* index */ , node] of this._nodes(startIndex, endIndex)) {
346
+ const startIndex = this._toAbsoluteIndex(start, this.length);
347
+ const endIndex = end === undefined ? this.length : this._toAbsoluteIndex(end, this.length);
348
+ for (const [, node] of this._nodes(startIndex, endIndex)) {
349
349
  result.push(node.value);
350
350
  }
351
351
  return result;
352
352
  }
353
- // TODO: Support "thisArg" argument
354
- some(callbackFn) {
353
+ some(predicate, thisArg) {
354
+ this._aCallable(predicate);
355
355
  for (const [index, node] of this._nodes(0, this.length)) {
356
- if (callbackFn(node.value, index, this)) {
356
+ if (predicate.call(thisArg, node.value, index, this)) {
357
357
  return true;
358
358
  }
359
359
  }
360
360
  return false;
361
361
  }
362
- sort(comparefn) {
362
+ sort(compareFn) {
363
363
  if (this.length > 1) {
364
- this._mergeSort(this._getSortCompare(comparefn));
364
+ const compare = this._getSortCompare(compareFn);
365
+ if (this.length < 8) {
366
+ this._insertionSort(compare);
367
+ }
368
+ else {
369
+ this._mergeSort(compare);
370
+ }
365
371
  }
366
372
  return this;
367
373
  }
368
- splice(start, deleteCount /* , ...items */) {
374
+ splice(start, deleteCount, ...items) {
369
375
  if (arguments.length === 0) {
370
- deleteCount = 0;
371
- }
372
- else if (arguments.length === 1) {
373
- start = this._toAbsoluteIndex(start, this.length);
374
- deleteCount = this.length - start;
375
- }
376
- else {
377
- start = this._toAbsoluteIndex(start, this.length);
378
- deleteCount = Math.min(Math.max(this._toIntegerOrInfinity(deleteCount), 0), this.length - start);
376
+ return new DoublyLinkedList();
379
377
  }
378
+ const startIndex = this._toAbsoluteIndex(start, this.length);
379
+ const delCount = arguments.length === 1
380
+ ? this.length - startIndex
381
+ : Math.min(Math.max(this._toIntegerOrInfinity(deleteCount), 0), this.length - startIndex);
380
382
  const deleted = new DoublyLinkedList();
381
- if (this.length > 0 && deleteCount > 0) {
382
- const prev = this._getNode(start - 1);
383
- let current = prev ? prev.next : this.head;
384
- for (let index = 0; index < deleteCount; index += 1) {
383
+ if (this.length > 0 && delCount > 0) {
384
+ const prev = this._getNode(startIndex - 1);
385
+ let current = prev ? prev.next : this._head;
386
+ for (let i = 0; i < delCount; i++) {
385
387
  deleted.push(current.value);
386
388
  current = current.next;
387
- this.length -= 1;
389
+ this._length -= 1;
388
390
  }
389
391
  if (prev === null) {
390
- this.head = current;
392
+ this._head = current;
391
393
  if (current) {
392
394
  current.prev = null;
393
395
  }
@@ -398,73 +400,99 @@ class DoublyLinkedList {
398
400
  current.prev = prev;
399
401
  }
400
402
  else {
401
- this.tail = prev;
403
+ this._tail = prev;
402
404
  }
403
405
  }
404
406
  }
405
- const items = Array.prototype.slice.call(arguments, 2, arguments.length);
406
407
  if (items.length > 0) {
407
- let current, next;
408
- if (start === 0) {
409
- next = this.head;
410
- this.head = new Node_1.Node(items.shift());
411
- current = this.head;
412
- this.length += 1;
408
+ let current;
409
+ let next;
410
+ if (startIndex === 0) {
411
+ next = this._head;
412
+ this._head = new Node_1.Node(items.shift());
413
+ current = this._head;
414
+ this._length += 1;
413
415
  }
414
416
  else {
415
- current = this._getNode(start - 1);
417
+ current = this._getNode(startIndex - 1);
416
418
  next = current.next;
417
419
  }
418
420
  for (const item of items) {
419
421
  current.next = new Node_1.Node(item);
420
422
  current.next.prev = current;
421
423
  current = current.next;
422
- this.length += 1;
424
+ this._length += 1;
423
425
  }
424
426
  current.next = next;
425
427
  if (next) {
426
428
  next.prev = current;
427
429
  }
428
430
  else {
429
- this.tail = current;
431
+ this._tail = current;
430
432
  }
431
433
  }
432
434
  return deleted;
433
435
  }
434
436
  toLocaleString(locales, options) {
435
- let result = '';
436
437
  if (this.length === 0) {
437
- return result;
438
+ return "";
438
439
  }
439
- const separator = ',';
440
- for (const [index, node] of this._nodes(0, this.length)) {
441
- const value = node.value == null ? "" : node.value;
442
- if (index !== this.length - 1) {
443
- result = result.concat(value.toLocaleString(locales, options)) + separator;
440
+ const parts = [];
441
+ for (const [, node] of this._nodes(0, this.length)) {
442
+ const value = node.value;
443
+ if (value == null) {
444
+ parts.push("");
444
445
  }
445
446
  else {
446
- result = result.concat(value.toLocaleString(locales, options));
447
+ parts.push(value.toLocaleString(locales, options));
447
448
  }
448
449
  }
449
- return result;
450
+ return parts.join(",");
451
+ }
452
+ toReversed() {
453
+ return this.slice().reverse();
454
+ }
455
+ toSorted(compareFn) {
456
+ if (compareFn !== undefined && !this._isCallable(compareFn)) {
457
+ let value;
458
+ if (compareFn === null)
459
+ value = "null";
460
+ else if (Array.isArray(compareFn))
461
+ value = Object.prototype.toString.call(compareFn);
462
+ else if (typeof compareFn === "object")
463
+ value = "#<Object>";
464
+ else
465
+ value = String(compareFn);
466
+ throw TypeError(`The comparison function must be either a function or undefined: ${value}`);
467
+ }
468
+ return this.slice().sort(compareFn);
469
+ }
470
+ toSpliced(start, deleteCount, ...items) {
471
+ const copy = this.slice();
472
+ if (arguments.length === 0) {
473
+ return copy;
474
+ }
475
+ else if (arguments.length === 1) {
476
+ copy.splice(start);
477
+ }
478
+ else {
479
+ copy.splice(start, deleteCount, ...items);
480
+ }
481
+ return copy;
450
482
  }
451
483
  toString() {
452
484
  return this.join(",");
453
485
  }
454
- unshift(...values) {
455
- const { length: valuesLength } = values;
456
- for (let index = valuesLength - 1; index >= 0; index -= 1) {
457
- const newNode = new Node_1.Node(values[index]);
486
+ unshift(...items) {
487
+ for (let i = items.length - 1; i >= 0; i--) {
488
+ const newNode = new Node_1.Node(items[i]);
458
489
  if (this.length === 0) {
459
490
  this._insertFirst(newNode);
460
491
  }
461
- else if (this.head !== null) {
462
- this._insertBefore(this.head, newNode);
463
- }
464
492
  else {
465
- continue;
493
+ this._insertBefore(this._head, newNode);
466
494
  }
467
- if (this.rearrangeOnCreation) {
495
+ if (!this._accessOnly) {
468
496
  this._rearrange(newNode);
469
497
  }
470
498
  }
@@ -473,25 +501,35 @@ class DoublyLinkedList {
473
501
  values() {
474
502
  return this._values();
475
503
  }
504
+ with(index, value) {
505
+ const relativeIndex = this._toIntegerOrInfinity(index);
506
+ const actualIndex = relativeIndex < 0 ? this.length + relativeIndex : relativeIndex;
507
+ if (actualIndex >= this.length || actualIndex < 0) {
508
+ throw new RangeError("Invalid index : " + index);
509
+ }
510
+ const copy = this.slice();
511
+ const node = copy._getNode(actualIndex);
512
+ if (node !== null) {
513
+ node.value = value;
514
+ }
515
+ return copy;
516
+ }
476
517
  // Public custom methods
477
518
  insert(index, value) {
478
519
  if (index === undefined || arguments.length < 2) {
479
520
  return undefined;
480
521
  }
481
- index = this._toAbsoluteIndex(index, this.length);
482
- if (index === 0) {
522
+ const idx = this._toAbsoluteIndex(index, this.length);
523
+ if (idx === 0) {
483
524
  return this.unshift(value);
484
525
  }
485
- if (index === this.length) {
526
+ if (idx === this.length) {
486
527
  return this.push(value);
487
528
  }
488
- const prev = this._getNode(index - 1);
489
- if (prev === null) {
490
- return undefined;
491
- }
529
+ const prev = this._getNode(idx - 1);
492
530
  const newNode = new Node_1.Node(value);
493
531
  this._insertAfter(prev, newNode);
494
- if (this.rearrangeOnCreation) {
532
+ if (!this._accessOnly) {
495
533
  this._rearrange(newNode);
496
534
  }
497
535
  return this.length;
@@ -499,17 +537,17 @@ class DoublyLinkedList {
499
537
  isEmpty() {
500
538
  return this.length === 0;
501
539
  }
502
- isEqual(value) {
503
- if (!(this._isIterable(value))) {
540
+ isEqual(other) {
541
+ if (!this._isIterable(other)) {
504
542
  throw TypeError("The value should be iterable");
505
543
  }
506
- if (this.length !== value.length) {
544
+ if (this.length !== other.length) {
507
545
  return false;
508
546
  }
509
- const values = value.values();
510
- for (const [/* index */ , node] of this._nodes(0, this.length)) {
511
- const currentValue = values.next();
512
- if (!(this._sameValue(node.value, currentValue.value))) {
547
+ const otherIterator = other[Symbol.iterator]();
548
+ for (const [, node] of this._nodes(0, this.length)) {
549
+ const otherValue = otherIterator.next();
550
+ if (!this._sameValue(node.value, otherValue.value)) {
513
551
  return false;
514
552
  }
515
553
  }
@@ -519,23 +557,21 @@ class DoublyLinkedList {
519
557
  if (this.length === 0 || index === undefined) {
520
558
  return undefined;
521
559
  }
522
- index = this._toAbsoluteIndex(index, this.length);
523
- if (index >= this.length) {
524
- return undefined;
525
- }
526
- const node = this._getNode(index);
527
- if (node === null) {
560
+ const idx = this._toAbsoluteIndex(index, this.length);
561
+ if (idx >= this.length) {
528
562
  return undefined;
529
563
  }
564
+ const node = this._getNode(idx);
530
565
  const value = node.value;
531
566
  this._remove(node);
532
567
  return value;
533
568
  }
534
- // Protected helping methods
569
+ // Protected methods
535
570
  _getIndexByNode(node) {
536
571
  let count = 0;
537
- while (node.prev) {
538
- node = node.prev;
572
+ let current = node;
573
+ while (current.prev) {
574
+ current = current.prev;
539
575
  count += 1;
540
576
  }
541
577
  return count;
@@ -544,27 +580,27 @@ class DoublyLinkedList {
544
580
  if (index < 0 || index >= this.length) {
545
581
  return null;
546
582
  }
547
- let node = this.head;
583
+ let node = this._head;
548
584
  let counter = 0;
549
585
  while (node) {
550
586
  if (counter === index) {
551
587
  break;
552
588
  }
553
589
  node = node.next;
554
- counter = counter + 1;
590
+ counter += 1;
555
591
  }
556
592
  return node;
557
593
  }
558
594
  _insertFirst(newNode) {
559
- this.head = newNode;
560
- this.tail = newNode;
561
- this.length += 1;
595
+ this._head = newNode;
596
+ this._tail = newNode;
597
+ this._length += 1;
562
598
  }
563
599
  _insertBefore(existingNode, newNode) {
564
- if (existingNode.isEqual(this.head)) {
600
+ if (existingNode.isEqual(this._head)) {
565
601
  newNode.next = existingNode;
566
602
  newNode.prev = null;
567
- this.head = newNode;
603
+ this._head = newNode;
568
604
  }
569
605
  else if (existingNode.prev !== null) {
570
606
  newNode.next = existingNode;
@@ -572,46 +608,46 @@ class DoublyLinkedList {
572
608
  existingNode.prev.next = newNode;
573
609
  }
574
610
  existingNode.prev = newNode;
575
- this.length += 1;
611
+ this._length += 1;
576
612
  }
577
613
  _insertAfter(existingNode, newNode) {
578
614
  newNode.prev = existingNode;
579
- if (existingNode.isEqual(this.tail)) {
615
+ if (existingNode.isEqual(this._tail)) {
580
616
  newNode.next = null;
581
- this.tail = newNode;
617
+ this._tail = newNode;
582
618
  }
583
619
  else if (existingNode.next !== null) {
584
620
  newNode.next = existingNode.next;
585
621
  existingNode.next.prev = newNode;
586
622
  }
587
623
  existingNode.next = newNode;
588
- this.length += 1;
624
+ this._length += 1;
589
625
  }
590
626
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
591
- _rearrange(node) {
627
+ _rearrange(_node) {
592
628
  return undefined;
593
629
  }
594
630
  _remove(node) {
595
- if (node.isEqual(this.head)) {
631
+ if (node.isEqual(this._head)) {
596
632
  this.shift();
597
633
  }
598
- else if (node.isEqual(this.tail)) {
634
+ else if (node.isEqual(this._tail)) {
599
635
  this.pop();
600
636
  }
601
637
  else if (node.next !== null && node.prev !== null) {
602
638
  node.next.prev = node.prev;
603
639
  node.prev.next = node.next;
604
- this.length -= 1;
640
+ this._length -= 1;
605
641
  }
606
642
  }
607
643
  _removeLast() {
608
- this.head = null;
609
- this.tail = null;
610
- this.length = 0;
644
+ this._head = null;
645
+ this._tail = null;
646
+ this._length = 0;
611
647
  }
612
- // Private helping methods
648
+ // Private methods
613
649
  *_entries() {
614
- let node = this.head;
650
+ let node = this._head;
615
651
  let counter = 0;
616
652
  while (node) {
617
653
  yield [counter, node.value];
@@ -620,38 +656,54 @@ class DoublyLinkedList {
620
656
  }
621
657
  }
622
658
  _extend(iterable) {
623
- if (!(this._isIterable(iterable))) {
659
+ if (!this._isIterable(iterable)) {
624
660
  throw TypeError("The value should be iterable");
625
661
  }
626
- for (const currentValue of iterable) {
627
- this.push(currentValue);
662
+ for (const value of iterable) {
663
+ const newNode = new Node_1.Node(value);
664
+ if (this.length === 0) {
665
+ this._insertFirst(newNode);
666
+ }
667
+ else {
668
+ this._insertAfter(this._tail, newNode);
669
+ }
628
670
  }
629
671
  }
630
- _getSortCompare(comparefn) {
631
- return function (x, y) {
672
+ _getSortCompare(compareFn) {
673
+ return (x, y) => {
632
674
  if (y === undefined)
633
675
  return -1;
634
676
  if (x === undefined)
635
677
  return 1;
636
- if (comparefn !== undefined)
637
- return +comparefn(x, y) || 0;
638
- return String(x) > String(y) ? 1 : -1;
678
+ if (compareFn !== undefined)
679
+ return +compareFn(x, y) || 0;
680
+ const xStr = String(x);
681
+ const yStr = String(y);
682
+ return xStr > yStr ? 1 : xStr < yStr ? -1 : 0;
639
683
  };
640
684
  }
641
685
  _isCallable(fn) {
642
- return (typeof fn === 'function');
686
+ return typeof fn === "function";
687
+ }
688
+ _aCallable(argument) {
689
+ if (this._isCallable(argument))
690
+ return argument;
691
+ const type = typeof argument;
692
+ const value = this._tryToString(argument);
693
+ const typePrefix = type !== "undefined" ? type + " " : "";
694
+ throw TypeError(`${typePrefix}${value} is not a function`);
643
695
  }
644
696
  _isIterable(obj) {
645
697
  if (obj == null) {
646
698
  return false;
647
699
  }
648
- return typeof obj[Symbol.iterator] === 'function';
700
+ return typeof obj[Symbol.iterator] === "function";
649
701
  }
650
702
  _isStrictlyEqual(x, y) {
651
703
  return x === y;
652
704
  }
653
705
  *_keys() {
654
- let node = this.head;
706
+ let node = this._head;
655
707
  let counter = 0;
656
708
  while (node) {
657
709
  yield counter;
@@ -659,15 +711,10 @@ class DoublyLinkedList {
659
711
  counter += 1;
660
712
  }
661
713
  }
662
- _merge(head1, head2, comparefn) {
663
- if (head1 == null) {
664
- return head2;
665
- }
666
- else if (head2 == null) {
667
- return head1;
668
- }
669
- let node, head;
670
- if (comparefn(head1.value, head2.value) <= 0) {
714
+ _merge(head1, head2, compareFn) {
715
+ let node;
716
+ let head;
717
+ if (compareFn(head1.value, head2.value) <= 0) {
671
718
  head = node = head1;
672
719
  head1 = head1.next;
673
720
  }
@@ -676,7 +723,7 @@ class DoublyLinkedList {
676
723
  head2 = head2.next;
677
724
  }
678
725
  while (head1 !== null && head2 !== null) {
679
- if (comparefn(head1.value, head2.value) <= 0) {
726
+ if (compareFn(head1.value, head2.value) <= 0) {
680
727
  node.next = head1;
681
728
  head1.prev = node;
682
729
  node = head1;
@@ -699,13 +746,12 @@ class DoublyLinkedList {
699
746
  }
700
747
  return head;
701
748
  }
702
- _mergeSort(comparefn) {
703
- const lists = [];
704
- let start = this.head;
705
- let end;
749
+ _mergeSort(compareFn) {
750
+ let lists = [];
751
+ let start = this._head;
706
752
  while (start !== null) {
707
- end = start;
708
- while (end.next !== null && comparefn(end.value, end.next.value) <= 0) {
753
+ let end = start;
754
+ while (end.next !== null && compareFn(end.value, end.next.value) <= 0) {
709
755
  end = end.next;
710
756
  }
711
757
  const next = end.next;
@@ -715,38 +761,79 @@ class DoublyLinkedList {
715
761
  start = next;
716
762
  }
717
763
  while (lists.length > 1) {
718
- const first = lists.shift();
719
- const second = lists.shift();
720
- if (first !== undefined && second !== undefined) {
721
- lists.push(this._merge(first, second, comparefn));
764
+ const merged = [];
765
+ for (let i = 0; i < lists.length; i += 2) {
766
+ if (i + 1 < lists.length) {
767
+ merged.push(this._merge(lists[i], lists[i + 1], compareFn));
768
+ }
769
+ else {
770
+ merged.push(lists[i]);
771
+ }
722
772
  }
773
+ lists = merged;
723
774
  }
724
- this.tail = lists[0];
725
- this.head = lists[0];
726
- while (this.tail && this.tail.next) {
727
- this.tail = this.tail.next;
775
+ this._tail = lists[0];
776
+ this._head = lists[0];
777
+ while (this._tail && this._tail.next) {
778
+ this._tail = this._tail.next;
779
+ }
780
+ }
781
+ _insertionSort(compareFn) {
782
+ let current = this._head.next;
783
+ while (current !== null) {
784
+ const next = current.next;
785
+ let position = current.prev;
786
+ while (position !== null && compareFn(position.value, current.value) > 0) {
787
+ position = position.prev;
788
+ }
789
+ if (position !== current.prev) {
790
+ if (current.prev) {
791
+ current.prev.next = current.next;
792
+ }
793
+ if (current.next) {
794
+ current.next.prev = current.prev;
795
+ }
796
+ else {
797
+ this._tail = current.prev;
798
+ }
799
+ if (position === null) {
800
+ current.prev = null;
801
+ current.next = this._head;
802
+ this._head.prev = current;
803
+ this._head = current;
804
+ }
805
+ else {
806
+ current.prev = position;
807
+ current.next = position.next;
808
+ if (position.next) {
809
+ position.next.prev = current;
810
+ }
811
+ position.next = current;
812
+ }
813
+ }
814
+ current = next;
728
815
  }
729
816
  }
730
817
  *_nodes(startIndex, endIndex) {
731
- let node = this.head;
818
+ let node = this._head;
732
819
  let counter = 0;
733
820
  while (node) {
734
821
  if (startIndex <= counter && counter < endIndex) {
735
822
  yield [counter, node];
736
823
  }
737
824
  node = node.next;
738
- counter = counter + 1;
825
+ counter += 1;
739
826
  }
740
827
  }
741
828
  *_nodesReverse(startIndex, endIndex) {
742
- let node = this.tail;
829
+ let node = this._tail;
743
830
  let counter = this.length - 1;
744
831
  while (node) {
745
832
  if (startIndex <= counter && counter < endIndex) {
746
833
  yield [counter, node];
747
834
  }
748
835
  node = node.prev;
749
- counter = counter - 1;
836
+ counter -= 1;
750
837
  }
751
838
  }
752
839
  _sameValue(x, y) {
@@ -760,6 +847,8 @@ class DoublyLinkedList {
760
847
  return integer < 0 ? Math.max(integer + length, 0) : Math.min(integer, length);
761
848
  }
762
849
  _toIntegerOrInfinity(argument) {
850
+ if (argument === undefined)
851
+ return 0;
763
852
  const number = +argument;
764
853
  return number !== number || number === 0 ? 0 : Math.trunc(number);
765
854
  }
@@ -767,12 +856,12 @@ class DoublyLinkedList {
767
856
  try {
768
857
  return String(argument);
769
858
  }
770
- catch (error) {
771
- return 'Object';
859
+ catch (_a) {
860
+ return "Object";
772
861
  }
773
862
  }
774
863
  *_values() {
775
- let node = this.head;
864
+ let node = this._head;
776
865
  while (node) {
777
866
  yield node.value;
778
867
  node = node.next;