@empathyco/x-components
Version:
Empathy X Components
178 lines (176 loc) • 5.48 kB
JavaScript
/**
* Default {@link XPriorityQueueNode} implementation.
*
* @public
*/
class BaseXPriorityQueueNode {
constructor(key, priority, data = {}) {
this.key = key;
this.priority = priority;
this.data = data;
}
/**
* Returns a string representation of this object. The string representation consists of: its
* priority, enclosed in square brackets (`[]`), followed by its key, an arrow `(->)` and the
* data converted to a string using JSON.stringify.
*
* @example
* ```
* [10] 1 -> { replaceable: false, randomKey: randomValue }
* ```
*
* @returns A string representation of this object.
*
* @public
*/
toString() {
return `[${this.priority}] ${String(this.key)} -> ${JSON.stringify(this.data)}`;
}
}
/**.
* Default {@link XPriorityQueue} implementation.
*
* Method big-O
* ---------------------------
* - push O(n)
* - pop O(1)
* - peek O(1)
* - at O(1)
*
* @public
*/
class BaseXPriorityQueue {
/**
* Creates a new {@link XPriorityQueue}.
*
* @param comparatorFn - Comparator - the comparator that will be used to order this queue.
* By default, the elements will be sorted in descending order (an element with priority 1 will
* be higher in the queue than another with priority 0).
*/
constructor(comparatorFn = (a, b) => a < b) {
/**
* The list of stored {@link XPriorityQueueNode | nodes}.
*
* @internal
*/
this.nodes = [];
this.comparatorFn = comparatorFn;
}
/**
* The `keys` property of a {@link XPriorityQueue} represents the keys of that queue. The value is
* an array of the parametrized `Key` type.
*
* @returns The list of keys.
*/
get keys() {
return this.nodes.map(({ key }) => key);
}
/**.
* See {@link XPriorityQueue.push}.
*
* @remarks
* If the optional data has a 'replaceable: true' and a similar key is already in the queue,
* the previous key will be removed and the new one will be inserted to the queue at the
* correct position based on its new priority.
*
* @param key - The key to insert.
* @param priority - The priority to order the element in the queue.
* @param data - The extra data associated to a key and priority pair.
*/
push(key, priority, data) {
const node = new BaseXPriorityQueueNode(key, priority, data);
if (this.isEmpty()) {
this.nodes.push(node);
}
else {
this.pushAndSort(node);
}
}
/**
* Inserts the node into the queue in the correct position based on the comparator function.
*
* @param newNode - The node to be inserted.
*
* @internal
*/
pushAndSort(newNode) {
const replaceableIndex = this.nodes.findIndex(node => node.key === newNode.key);
if (replaceableIndex > -1 && this.nodes[replaceableIndex].data.replaceable) {
this.nodes.splice(replaceableIndex, 1);
}
const insertAtIndex = this.nodes.findIndex(node => this.comparatorFn(node.priority, newNode.priority));
if (insertAtIndex === -1) {
this.nodes.push(newNode);
}
else {
this.nodes.splice(insertAtIndex, 0, newNode);
}
}
/**
* See {@link XPriorityQueue.pop}.
*
* @returns The head {@link XPriorityQueueNode | node} of the queue or undefined if it is empty.
*/
pop() {
return this.nodes.shift();
}
/**
* Retrieves, but does not remove, the head {@link XPriorityQueueNode | node} of the queue.
*
* @returns The head {@link XPriorityQueueNode | node} of the queue.
*/
peek() {
return this.nodes[0];
}
/**
* Retrieves the {@link XPriorityQueueNode | node} at a given position.
*
* @param index - The position to look at.
*
* @returns The {@link XPriorityQueueNode | node} at the passed position in the queue.
*/
at(index) {
return this.nodes[index];
}
/**
* Removes all the {@link XPriorityQueueNode | nodes} from the queue.
*/
clear() {
this.nodes.length = 0;
}
/**
* Checks if the queue is empty.
*
* @returns True if the queue is empty, false otherwise.
*/
isEmpty() {
return this.nodes.length === 0;
}
/**
* Retrieves the number of {@link XPriorityQueueNode | nodes} stored in the queue.
*
* @returns The number of {@link XPriorityQueueNode | nodes} stored in the queue.
*/
size() {
return this.nodes.length;
}
/**
* Returns a string representation of this collection. The string representation consists of a
* list of the queue {@link XPriorityQueueNode | nodes} split in multiple lines, one for each
* one. Nodes are converted to strings as by toString().
*
* @example
* ```
* [10] 1 -> { replaceable: false, a: 'b' }
* [20] 2 -> { replaceable: false }
* [30] 3 -> { replaceable: false, c: 1 }
* ```
*
* @returns A string representation of the queue.
*/
toString() {
return this.nodes.reduce((output, node) => output.concat(node.toString(), '\n'), '');
}
}
export { BaseXPriorityQueue, BaseXPriorityQueueNode };
//# sourceMappingURL=x-priority-queue.js.map