Initial commit
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
class DoubleLinkedListNode {
|
||||
constructor(key, value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.next = null;
|
||||
this.prev = null;
|
||||
};
|
||||
};
|
||||
|
||||
class DoubleLinkedList {
|
||||
constructor() {
|
||||
this.map = new Map();
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
};
|
||||
|
||||
getElement(id) {
|
||||
const element = this.map.get(id);
|
||||
if (!element) return;
|
||||
|
||||
return element.value;
|
||||
}
|
||||
|
||||
hasElement(id) {
|
||||
return this.map.has(id);
|
||||
}
|
||||
|
||||
isEmpty() {
|
||||
return this.head === null;
|
||||
}
|
||||
|
||||
addFirst(key, value) {
|
||||
if (this.map.has(key)) this.removeItem(key);
|
||||
|
||||
const newNode = new DoubleLinkedListNode(key, value);
|
||||
|
||||
const oldHead = this.head;
|
||||
this.head = newNode;
|
||||
this.head.prev = null;
|
||||
|
||||
if (oldHead) {
|
||||
oldHead.prev = newNode;
|
||||
this.head.next = oldHead;
|
||||
};
|
||||
|
||||
this.map.set(key, {
|
||||
value,
|
||||
node: newNode
|
||||
});
|
||||
};
|
||||
|
||||
accumulateItem(key, value) {
|
||||
if (isNaN(value)) return;
|
||||
|
||||
const entry = this.map.get(key);
|
||||
const updatedValue = entry ? entry.value + value : value;
|
||||
|
||||
this.addItem(key, updatedValue);
|
||||
}
|
||||
|
||||
addItem(key, value) {
|
||||
if (this.map.has(key)) this.removeItem(key);
|
||||
|
||||
const temp = new DoubleLinkedListNode(key, value);
|
||||
|
||||
if (!this.head) {
|
||||
this.head = temp;
|
||||
this.tail = temp;
|
||||
} else {
|
||||
this.tail.next = temp;
|
||||
temp.prev = this.tail;
|
||||
this.tail = this.tail.next;
|
||||
};
|
||||
|
||||
this.map.set(key, {
|
||||
value,
|
||||
node: temp
|
||||
});
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
removeItem(key) {
|
||||
const entry = this.map.get(key);
|
||||
if (!entry) return;
|
||||
|
||||
const node = entry.node;
|
||||
if (node.prev) node.prev.next = node.next;
|
||||
if (node.next) node.next.prev = node.prev;
|
||||
|
||||
if (node === this.head) this.head = node.next;
|
||||
if (node === this.tail) this.tail = node.prev;
|
||||
|
||||
this.map.delete(key);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
each(cb) {
|
||||
if (this.isEmpty()) return;
|
||||
if (!cb) return;
|
||||
|
||||
let isRunning = true;
|
||||
let current = this.head;
|
||||
|
||||
while (current && (isRunning === undefined || isRunning)) { // I'm afraid this would backfire one day
|
||||
isRunning = cb(current.key, current.value);
|
||||
|
||||
current = current.next;
|
||||
};
|
||||
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
clearEach(cb) {
|
||||
if (this.isEmpty()) return;
|
||||
if (!cb) return;
|
||||
|
||||
let current = this.head;
|
||||
while (current) {
|
||||
cb(current.key, current.value);
|
||||
|
||||
current.prev = null;
|
||||
current = current.next;
|
||||
};
|
||||
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
|
||||
this.map.clear();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = DoubleLinkedList;
|
||||
Reference in New Issue
Block a user