js-fundamentals 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 +100 -0
- package/package.json +1 -1
- package/src/priorityqueue/index.js +27 -1
- package/tests/priorityqueue.test.js +18 -0
package/README.md
CHANGED
|
@@ -1 +1,101 @@
|
|
|
1
1
|
# fundamentals
|
|
2
|
+
|
|
3
|
+
Small JavaScript data-structure utilities (ESM).
|
|
4
|
+
|
|
5
|
+
Currently included:
|
|
6
|
+
|
|
7
|
+
- `Queue`: FIFO queue
|
|
8
|
+
- `PriorityQueue`: queue ordered by numeric priority (ascending by default)
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm i js-fundamentals
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
This package is **ESM-only** (`"type": "module"`).
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { Queue, PriorityQueue } from "js-fundamentals";
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Queue
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import { Queue } from "js-fundamentals";
|
|
28
|
+
|
|
29
|
+
const q = new Queue();
|
|
30
|
+
q.enqueue("a");
|
|
31
|
+
q.enqueue("b");
|
|
32
|
+
|
|
33
|
+
q.peek(); // "a"
|
|
34
|
+
q.dequeue(); // "a"
|
|
35
|
+
q.size(); // 1
|
|
36
|
+
q.toArray(); // ["b"]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### PriorityQueue
|
|
40
|
+
|
|
41
|
+
`PriorityQueue` stores `(item, priority)` pairs internally and always dequeues the next item based on priority.
|
|
42
|
+
|
|
43
|
+
By default it is **ascending** (lower numbers come out first). Pass `{ descending: true }` to the constructor for **descending** order.
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
import { PriorityQueue } from "js-fundamentals";
|
|
47
|
+
|
|
48
|
+
const pq = new PriorityQueue(); // ascending
|
|
49
|
+
pq.enqueue("low", 10);
|
|
50
|
+
pq.enqueue("high", 1);
|
|
51
|
+
|
|
52
|
+
pq.dequeue(); // "high"
|
|
53
|
+
pq.toArray(); // ["low"]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Descending order:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
const pq = new PriorityQueue({ descending: true }); // descending
|
|
60
|
+
pq.enqueue("low", 1);
|
|
61
|
+
pq.enqueue("high", 10);
|
|
62
|
+
|
|
63
|
+
pq.dequeue(); // "high"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
### `new Queue()`
|
|
69
|
+
|
|
70
|
+
- `enqueue(item): void`
|
|
71
|
+
- `dequeue(): any | undefined` (returns `undefined` if empty)
|
|
72
|
+
- `peek(): any | undefined` (returns `undefined` if empty)
|
|
73
|
+
- `isEmpty(): boolean`
|
|
74
|
+
- `size(): number`
|
|
75
|
+
- `toArray(): any[]` (returns the internal backing array)
|
|
76
|
+
|
|
77
|
+
### `new PriorityQueue(options?)`
|
|
78
|
+
|
|
79
|
+
Extends `Queue`.
|
|
80
|
+
|
|
81
|
+
- `options.descending?: boolean` (default: `false`)
|
|
82
|
+
- `enqueue(item, priority): void` (`priority` should be a number)
|
|
83
|
+
- `dequeue(): any | undefined` (returns `undefined` if empty)
|
|
84
|
+
- `peek(): any | undefined` (returns `undefined` if empty)
|
|
85
|
+
- `isEmpty(): boolean`
|
|
86
|
+
- `size(): number`
|
|
87
|
+
- `toArray(): any[]` (returns only items, not priorities)
|
|
88
|
+
- `changePriority(item, newPriority): void`
|
|
89
|
+
- Finds an existing item and updates its priority, then re-sorts the queue.
|
|
90
|
+
- Matching rules:
|
|
91
|
+
- Uses strict equality (`===`) for non-objects
|
|
92
|
+
- For non-null objects, falls back to `JSON.stringify` comparison
|
|
93
|
+
- Throws `Error("Item not found")` if no match is found.
|
|
94
|
+
|
|
95
|
+
## Development
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npm test
|
|
99
|
+
npm run lint
|
|
100
|
+
npm run format
|
|
101
|
+
```
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import Queue from "../queue";
|
|
2
2
|
|
|
3
3
|
class PriorityQueue extends Queue {
|
|
4
|
-
constructor(
|
|
4
|
+
constructor(options = {}) {
|
|
5
5
|
super();
|
|
6
|
+
const { descending = false } = options;
|
|
6
7
|
this.descending = descending;
|
|
7
8
|
}
|
|
8
9
|
|
|
@@ -32,6 +33,31 @@ class PriorityQueue extends Queue {
|
|
|
32
33
|
toArray() {
|
|
33
34
|
return this.items.map((item) => item.item);
|
|
34
35
|
}
|
|
36
|
+
|
|
37
|
+
changePriority(item, newPriority) {
|
|
38
|
+
const index = this.items.findIndex((i) => {
|
|
39
|
+
if (i.item === item) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
typeof i.item === "object" &&
|
|
45
|
+
typeof item === "object" &&
|
|
46
|
+
i.item !== null &&
|
|
47
|
+
item !== null
|
|
48
|
+
) {
|
|
49
|
+
return JSON.stringify(i.item) === JSON.stringify(item);
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
});
|
|
53
|
+
if (index === -1) {
|
|
54
|
+
throw new Error("Item not found");
|
|
55
|
+
}
|
|
56
|
+
this.items[index].priority = newPriority;
|
|
57
|
+
this.items.sort((a, b) =>
|
|
58
|
+
this.descending ? b.priority - a.priority : a.priority - b.priority,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
35
61
|
}
|
|
36
62
|
|
|
37
63
|
export default PriorityQueue;
|
|
@@ -23,6 +23,15 @@ describe("PriorityQueue", () => {
|
|
|
23
23
|
expect(queue.isEmpty()).toBe(false);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
it("should dequeue an item with descending priority", () => {
|
|
27
|
+
const queue = new PriorityQueue({ descending: true });
|
|
28
|
+
queue.enqueue(1, 1);
|
|
29
|
+
queue.enqueue(2, 2);
|
|
30
|
+
queue.enqueue(3, 3);
|
|
31
|
+
expect(queue.dequeue()).toBe(3);
|
|
32
|
+
expect(queue.isEmpty()).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
|
|
26
35
|
it("should peek at the front item", () => {
|
|
27
36
|
const queue = new PriorityQueue();
|
|
28
37
|
queue.enqueue(3, 3);
|
|
@@ -55,4 +64,13 @@ describe("PriorityQueue", () => {
|
|
|
55
64
|
queue.enqueue(1, 1);
|
|
56
65
|
expect(queue.toArray()).toEqual([1, 2, 3]);
|
|
57
66
|
});
|
|
67
|
+
|
|
68
|
+
it("should change the priority of an item", () => {
|
|
69
|
+
const queue = new PriorityQueue();
|
|
70
|
+
queue.enqueue({ id: 1 }, 1);
|
|
71
|
+
queue.enqueue({ id: 2 }, 2);
|
|
72
|
+
queue.enqueue({ id: 3 }, 3);
|
|
73
|
+
queue.changePriority({ id: 2 }, 4);
|
|
74
|
+
expect(queue.toArray()).toEqual([{ id: 1 }, { id: 3 }, { id: 2 }]);
|
|
75
|
+
});
|
|
58
76
|
});
|