list-toolkit 1.0.1 → 1.0.2

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 CHANGED
@@ -1,4 +1,7 @@
1
- # List toolkit
1
+ # List toolkit [![NPM version][npm-img]][npm-url]
2
+
3
+ [npm-img]: https://img.shields.io/npm/v/list-toolkit.svg
4
+ [npm-url]: https://npmjs.org/package/list-toolkit
2
5
 
3
6
  List-based **efficient** data structures to organize your objects.
4
7
  This is a pure JavaScript module with no dependencies
@@ -10,6 +13,7 @@ The toolkit provides the following data structures with a full set of efficientl
10
13
  * **ListHead**: a doubly linked list that uses custom properties on external objects to link them around.
11
14
  * Using different custom properties the same object can be linked in different ways.
12
15
  * **SList**: a singly linked list implemented as a container.
16
+ * **SListHead**: a singly linked list that uses custom properties on external objects to link them around.
13
17
  * Using different custom properties the same object can be linked in different ways.
14
18
  * **Cache**: a List-based container with a limited capacity and an LRU policy of evicting old entries.
15
19
  * **MinHeap**: a classic heap data structure (a priority queue).
@@ -431,7 +435,10 @@ The main operations are:
431
435
 
432
436
  | Method | Description | Complexity |
433
437
  |------|-----------|-----|
434
- | `new MinHeap({less = (a, b) => a < b, equal: (a, b) => a === b}, ...args)` | create a new heap optionally from iterables or other heaps | *O(k)* |
438
+ | `new MinHeap({less = (a, b) => a < b, equal: (a, b) => a === b}, ...args)` | create a new heap and optionally populate it from iterables or other heaps | *O(k)* |
439
+ | `array` | get the underlying array organized as min heap | *O(1)* |
440
+ | `less` | get the comparison function | *O(1)* |
441
+ | `equal` | get the equality function | *O(1)* |
435
442
  | `length` | get the number of elements in the heap | *O(1)* |
436
443
  | `isEmpty` | check if the heap is empty | *O(1)* |
437
444
  | `top` | get the top element | *O(1)* |
@@ -440,6 +447,9 @@ The main operations are:
440
447
  | `push(value)` | add new element | *O(log(n))* |
441
448
  | `pushPop(value)` | add new element and then return the top element | *O(log(n))* |
442
449
  | `replaceTop(value)` | return the top element and then add new element | *O(log(n))* |
450
+ | `has(value)` | check if the heap contains an element | *O(n)* |
451
+ | `remove(value)` | remove an element | *O(n)* |
452
+ | `replace(value, newValue)` | replace an element | *O(n)* |
443
453
  | `releaseSorted()` | remove all elements and return them as an array in the reverse sorted order (the heap will be cleared) | *O(n)* |
444
454
  | `merge(...args)` | add elements from iterables or other heaps | *O(k)* |
445
455
  | `make(...args)` | return a new heap with the same options | *O(1)* |
@@ -454,6 +464,12 @@ The main operations are:
454
464
  | `MinHeap.push(heapArray, value, less = (a, b) => a < b)` | add new element | *O(log(n))* |
455
465
  | `MinHeap.pushPop(heapArray, value, less = (a, b) => a < b)` | add new element and then return the top element | *O(log(n))* |
456
466
  | `MinHeap.replaceTop(heapArray, value, less = (a, b) => a < b)` | return the top element and then add new element | *O(log(n))* |
467
+ | `MinHeap.findIndex(heapArray, item, equal = (a, b) => a === b)` | return the index of an element or -1| *O(n)* |
468
+ | `MinHead.removeByIndex(heapArray, index, less = (a, b) => a < b, equal = (a, b) => a === b)` | remove an element by index | *O(log(n))* |
469
+ | `MinHeap.replaceByIndex(heapArray, index, value, less = (a, b) => a < b, equal = (a, b) => a === b)` | replace an element by index | *O(log(n))* |
470
+ | `MinHead.has(heapArray, item, equal = (a, b) => a === b)` | check if the heap contains an element | *O(n)* |
471
+ | `MinHeap.remove(heapArray, item, less = (a, b) => a < b, equal = (a, b) => a === b)` | remove an element | *O(n)* |
472
+ | `MinHeap.replace(heapArray, item, newItem, less = (a, b) => a < b, equal = (a, b) => a === b)` | replace an element | *O(n)* |
457
473
  | `MinHeap.sort(heapArray, less = (a, b) => a < b)` | sort an array in place | *O(n * log(n))* |
458
474
 
459
475
  ## License
@@ -462,4 +478,5 @@ BSD 3-Clause "New" or "Revised" License. See the LICENSE file for details.
462
478
 
463
479
  ## Release History
464
480
 
481
+ * 1.0.1 *Fixed exports. Added more methods to `MinHeap`.*
465
482
  * 1.0.1 *Initial release.*
package/cjs/Cache.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.Cache = void 0;
7
7
  var _List = _interopRequireDefault(require("./List.js"));
8
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
9
  class Cache {
@@ -67,4 +67,5 @@ class Cache {
67
67
  return this.list.getReverseIterable();
68
68
  }
69
69
  }
70
+ exports.Cache = Cache;
70
71
  var _default = exports.default = Cache;
package/cjs/List.js CHANGED
@@ -3,12 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.ListValueNode = exports.ListNode = exports.List = void 0;
7
7
  class ListNode {
8
8
  constructor() {
9
9
  this.prev = this.next = this;
10
10
  }
11
11
  }
12
+ exports.ListNode = ListNode;
12
13
  const pop = head => {
13
14
  const rest = head.next;
14
15
  head.prev.next = head.next;
@@ -62,6 +63,7 @@ class ListValueNode extends ListNode {
62
63
  return this;
63
64
  }
64
65
  }
66
+ exports.ListValueNode = ListValueNode;
65
67
  class List extends ListNode {
66
68
  get isEmpty() {
67
69
  return this.next === this;
@@ -280,6 +282,7 @@ class List extends ListNode {
280
282
  return list;
281
283
  }
282
284
  }
285
+ exports.List = List;
283
286
  List.pop = pop;
284
287
  List.extract = extract;
285
288
  List.splice = splice;
package/cjs/ListHead.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.ListHead = void 0;
7
7
  var _utils = require("./utils.js");
8
8
  class ListHead {
9
9
  constructor(head = null, options) {
@@ -293,6 +293,7 @@ class ListHead {
293
293
  return list;
294
294
  }
295
295
  }
296
+ exports.ListHead = ListHead;
296
297
  ListHead.defaults = {
297
298
  nextName: 'next',
298
299
  prevName: 'prev'
package/cjs/MinHeap.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.MinHeap = void 0;
7
7
  var _utils = require("./utils.js");
8
8
  // the following functions are inlined:
9
9
 
@@ -166,6 +166,16 @@ class MinHeap {
166
166
  }
167
167
  return top;
168
168
  }
169
+ has(value) {
170
+ // return MinHeap.has(this.array, value, this.equal); // inlined
171
+ return this.array.findIndex(element => this.equal(element, value)) >= 0;
172
+ }
173
+ remove(value) {
174
+ return MinHeap.remove(this.array, value, this.less, this.equal);
175
+ }
176
+ replace(value, newValue) {
177
+ return MinHeap.replace(this.array, value, newValue, this.less, this.equal);
178
+ }
169
179
  releaseSorted() {
170
180
  MinHeap.sort(this.array, this.less);
171
181
  const array = this.array;
@@ -245,6 +255,46 @@ class MinHeap {
245
255
  down(heapArray, 0, less);
246
256
  return top;
247
257
  }
258
+ static has(heapArray, item, equal = MinHeap.defaults.equal) {
259
+ return heapArray.findIndex(element => equal(element, item)) >= 0;
260
+ }
261
+ static findIndex(heapArray, item, equal = MinHeap.defaults.equal) {
262
+ return heapArray.findIndex(element => equal(element, item));
263
+ }
264
+ static removeByIndex(heapArray, index, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
265
+ if (index < 0 || index >= heapArray.length) return this;
266
+ const last = heapArray.length - 1;
267
+ if (index !== last) {
268
+ const item = heapArray[index];
269
+ heapArray[index] = heapArray.pop();
270
+ if (less(heapArray[index], item)) up(heapArray, index, less);else down(heapArray, index, less);
271
+ } else heapArray.pop();
272
+ return this;
273
+ }
274
+ static remove(heapArray, item, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
275
+ const index = heapArray.findIndex(element => equal(element, item));
276
+ if (index < 0) return this;
277
+ const last = heapArray.length - 1;
278
+ if (index !== last) {
279
+ heapArray[index] = heapArray.pop();
280
+ if (less(heapArray[index], item)) up(heapArray, index, less);else down(heapArray, index, less);
281
+ } else heapArray.pop();
282
+ return this;
283
+ }
284
+ static replaceByIndex(heapArray, index, newItem, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
285
+ if (index < 0 || index >= heapArray.length) return this;
286
+ const item = heapArray[index];
287
+ heapArray[index] = newItem;
288
+ if (less(newItem, item)) up(heapArray, index, less);else down(heapArray, index, less);
289
+ return this;
290
+ }
291
+ static replace(heapArray, item, newItem, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
292
+ const index = heapArray.findIndex(element => equal(element, item));
293
+ if (index < 0) return this;
294
+ heapArray[index] = newItem;
295
+ if (less(newItem, item)) up(heapArray, index, less);else down(heapArray, index, less);
296
+ return this;
297
+ }
248
298
  static sort(heapArray, less = MinHeap.defaults.less) {
249
299
  if (heapArray.length <= 1) return heapArray;
250
300
  for (let n = heapArray.length - 1; n; --n) {
@@ -254,6 +304,7 @@ class MinHeap {
254
304
  return heapArray;
255
305
  }
256
306
  }
307
+ exports.MinHeap = MinHeap;
257
308
  MinHeap.defaults = {
258
309
  less: defaultLess,
259
310
  equal: defaultEqual
package/cjs/SList.js CHANGED
@@ -3,12 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.SListValueNode = exports.SListPtr = exports.SListNode = exports.SList = void 0;
7
7
  class SListNode {
8
8
  constructor() {
9
9
  this.next = this;
10
10
  }
11
11
  }
12
+ exports.SListNode = SListNode;
12
13
  const pop = prev => {
13
14
  const node = prev.next;
14
15
  prev.next = node.next;
@@ -78,6 +79,7 @@ class SListValueNode extends SListNode {
78
79
  return this;
79
80
  }
80
81
  }
82
+ exports.SListValueNode = SListValueNode;
81
83
  class SList extends SListNode {
82
84
  get isEmpty() {
83
85
  return this.next === this;
@@ -304,6 +306,7 @@ class SList extends SListNode {
304
306
  return list;
305
307
  }
306
308
  }
309
+ exports.SList = SList;
307
310
  SList.pop = pop;
308
311
  SList.extract = extract;
309
312
  SList.splice = splice;
@@ -314,7 +317,7 @@ SList.ValueNode = SListValueNode;
314
317
  SList.prototype.pop = SList.prototype.popFront;
315
318
  SList.prototype.push = SList.prototype.pushFront;
316
319
  SList.prototype.append = SList.prototype.appendBack;
317
- SList.SListPtr = class SListPtr {
320
+ class SListPtr {
318
321
  constructor(list, prev) {
319
322
  this.list = list;
320
323
  this.prev = prev || list;
@@ -332,5 +335,8 @@ SList.SListPtr = class SListPtr {
332
335
  clone() {
333
336
  return new SList.SListPtr(this.list, this.prev);
334
337
  }
335
- };
338
+ }
339
+ exports.SListPtr = SListPtr;
340
+ ;
341
+ SList.SListPtr = SListPtr;
336
342
  var _default = exports.default = SList;
package/cjs/SListHead.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.SListPtr = exports.SListHead = void 0;
7
7
  var _utils = require("./utils.js");
8
8
  class SListHead {
9
9
  constructor(head = null, options) {
@@ -330,6 +330,7 @@ class SListHead {
330
330
  return list;
331
331
  }
332
332
  }
333
+ exports.SListHead = SListHead;
333
334
  SListHead.defaults = {
334
335
  nextName: 'next'
335
336
  };
@@ -341,7 +342,7 @@ SListHead.Unsafe = class Unsafe {
341
342
  this.head = head;
342
343
  }
343
344
  };
344
- SListHead.SListPtr = class SListPtr {
345
+ class SListPtr {
345
346
  constructor(list, prev) {
346
347
  this.list = list;
347
348
  this.prev = prev || list.head;
@@ -359,5 +360,8 @@ SListHead.SListPtr = class SListPtr {
359
360
  clone() {
360
361
  return new SListHead.SListPtr(this.list, this.prev);
361
362
  }
362
- };
363
+ }
364
+ exports.SListPtr = SListPtr;
365
+ ;
366
+ SListHead.SListPtr = SListPtr;
363
367
  var _default = exports.default = SListHead;
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "list-toolkit",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "List-based data structures to organize your objects.",
5
5
  "type": "module",
6
6
  "exports": {
7
- "import": "./src/*",
8
- "default": "./cjs/*"
7
+ "./*": {
8
+ "require": "./cjs/*",
9
+ "default": "./src/*"
10
+ }
9
11
  },
10
12
  "scripts": {
11
13
  "test": "tape6 --flags FO",
package/src/Cache.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import List from './List.js';
4
4
 
5
- class Cache {
5
+ export class Cache {
6
6
  constructor(capacity = 10) {
7
7
  this.capacity = capacity;
8
8
  this.size = 0;
package/src/List.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- class ListNode {
3
+ export class ListNode {
4
4
  constructor() {
5
5
  this.prev = this.next = this;
6
6
  }
@@ -34,7 +34,7 @@ const splice = (head1, head2) => {
34
34
  return head1;
35
35
  };
36
36
 
37
- class ListValueNode extends ListNode {
37
+ export class ListValueNode extends ListNode {
38
38
  constructor(value) {
39
39
  super();
40
40
  this.value = value;
@@ -65,7 +65,7 @@ class ListValueNode extends ListNode {
65
65
  }
66
66
  }
67
67
 
68
- class List extends ListNode {
68
+ export class List extends ListNode {
69
69
  get isEmpty() {
70
70
  return this.next === this;
71
71
  }
package/src/ListHead.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {copyOptions} from './utils.js';
4
4
 
5
- class ListHead {
5
+ export class ListHead {
6
6
  constructor(head = null, options) {
7
7
  if (head instanceof ListHead) {
8
8
  ({nextName: this.nextName, prevName: this.prevName, head: this.head} = head);
package/src/MinHeap.js CHANGED
@@ -45,7 +45,7 @@ const down = (array, i, less = defaultLess, n = array.length) => {
45
45
  return array;
46
46
  };
47
47
 
48
- class MinHeap {
48
+ export class MinHeap {
49
49
  constructor(options, ...args) {
50
50
  copyOptions(this, MinHeap.defaults, options);
51
51
  this.array = [];
@@ -175,6 +175,19 @@ class MinHeap {
175
175
  return top;
176
176
  }
177
177
 
178
+ has(value) {
179
+ // return MinHeap.has(this.array, value, this.equal); // inlined
180
+ return this.array.findIndex(element => this.equal(element, value)) >= 0;
181
+ }
182
+
183
+ remove(value) {
184
+ return MinHeap.remove(this.array, value, this.less, this.equal);
185
+ }
186
+
187
+ replace(value, newValue) {
188
+ return MinHeap.replace(this.array, value, newValue, this.less, this.equal);
189
+ }
190
+
178
191
  releaseSorted() {
179
192
  MinHeap.sort(this.array, this.less);
180
193
  const array = this.array;
@@ -268,6 +281,56 @@ class MinHeap {
268
281
  return top;
269
282
  }
270
283
 
284
+ static has(heapArray, item, equal = MinHeap.defaults.equal) {
285
+ return heapArray.findIndex(element => equal(element, item)) >= 0;
286
+ }
287
+
288
+ static findIndex(heapArray, item, equal = MinHeap.defaults.equal) {
289
+ return heapArray.findIndex(element => equal(element, item));
290
+ }
291
+
292
+ static removeByIndex(heapArray, index, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
293
+ if (index < 0 || index >= heapArray.length) return this;
294
+ const last = heapArray.length - 1;
295
+ if (index !== last) {
296
+ const item = heapArray[index];
297
+ heapArray[index] = heapArray.pop();
298
+ if (less(heapArray[index], item)) up(heapArray, index, less);
299
+ else down(heapArray, index, less);
300
+ } else heapArray.pop();
301
+ return this;
302
+ }
303
+
304
+ static remove(heapArray, item, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
305
+ const index = heapArray.findIndex(element => equal(element, item));
306
+ if (index < 0) return this;
307
+ const last = heapArray.length - 1;
308
+ if (index !== last) {
309
+ heapArray[index] = heapArray.pop();
310
+ if (less(heapArray[index], item)) up(heapArray, index, less);
311
+ else down(heapArray, index, less);
312
+ } else heapArray.pop();
313
+ return this;
314
+ }
315
+
316
+ static replaceByIndex(heapArray, index, newItem, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
317
+ if (index < 0 || index >= heapArray.length) return this;
318
+ const item = heapArray[index];
319
+ heapArray[index] = newItem;
320
+ if (less(newItem, item)) up(heapArray, index, less);
321
+ else down(heapArray, index, less);
322
+ return this;
323
+ }
324
+
325
+ static replace(heapArray, item, newItem, less = MinHeap.defaults.less, equal = MinHeap.defaults.equal) {
326
+ const index = heapArray.findIndex(element => equal(element, item));
327
+ if (index < 0) return this;
328
+ heapArray[index] = newItem;
329
+ if (less(newItem, item)) up(heapArray, index, less);
330
+ else down(heapArray, index, less);
331
+ return this;
332
+ }
333
+
271
334
  static sort(heapArray, less = MinHeap.defaults.less) {
272
335
  if (heapArray.length <= 1) return heapArray;
273
336
  for (let n = heapArray.length - 1; n; --n) {
package/src/SList.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- class SListNode {
3
+ export class SListNode {
4
4
  constructor() {
5
5
  this.next = this;
6
6
  }
@@ -46,7 +46,7 @@ const getPrev = (list, node) => {
46
46
  return getPrevPrev(list, node).next;
47
47
  };
48
48
 
49
- class SListValueNode extends SListNode {
49
+ export class SListValueNode extends SListNode {
50
50
  constructor(value) {
51
51
  super();
52
52
  this.value = value;
@@ -65,7 +65,7 @@ class SListValueNode extends SListNode {
65
65
  }
66
66
  }
67
67
 
68
- class SList extends SListNode {
68
+ export class SList extends SListNode {
69
69
  get isEmpty() {
70
70
  return this.next === this;
71
71
  }
@@ -306,7 +306,7 @@ SList.prototype.pop = SList.prototype.popFront;
306
306
  SList.prototype.push = SList.prototype.pushFront;
307
307
  SList.prototype.append = SList.prototype.appendBack;
308
308
 
309
- SList.SListPtr = class SListPtr {
309
+ export class SListPtr {
310
310
  constructor(list, prev) {
311
311
  this.list = list;
312
312
  this.prev = prev || list;
@@ -325,5 +325,6 @@ SList.SListPtr = class SListPtr {
325
325
  return new SList.SListPtr(this.list, this.prev);
326
326
  }
327
327
  };
328
+ SList.SListPtr = SListPtr;
328
329
 
329
330
  export default SList;
package/src/SListHead.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {copyOptions} from './utils.js';
4
4
 
5
- class SListHead {
5
+ export class SListHead {
6
6
  constructor(head = null, options) {
7
7
  if (head instanceof SListHead) {
8
8
  ({nextName: this.nextName, head: this.head} = head);
@@ -330,7 +330,7 @@ SListHead.Unsafe = class Unsafe {
330
330
  }
331
331
  };
332
332
 
333
- SListHead.SListPtr = class SListPtr {
333
+ export class SListPtr {
334
334
  constructor(list, prev) {
335
335
  this.list = list;
336
336
  this.prev = prev || list.head;
@@ -349,5 +349,6 @@ SListHead.SListPtr = class SListPtr {
349
349
  return new SListHead.SListPtr(this.list, this.prev);
350
350
  }
351
351
  };
352
+ SListHead.SListPtr = SListPtr;
352
353
 
353
354
  export default SListHead;