linked-list-typescript
Version:
simple typescript linked-list with generics typing
209 lines • 6.11 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class LinkedList {
constructor(...values) {
this._head = this._tail = null;
this._length = 0;
if (values.length > 0) {
values.forEach((value) => {
this.append(value);
});
}
}
*iterator() {
let currentItem = this._head;
while (currentItem) {
yield currentItem.value;
currentItem = currentItem.next;
}
}
[Symbol.iterator]() {
return this.iterator();
}
get head() {
return this._head ? this._head.value : null;
}
get tail() {
return this._tail ? this._tail.value : null;
}
get length() {
return this._length;
}
// Adds the element at a specific position inside the linked list
insert(val, previousItem, checkDuplicates = false) {
if (checkDuplicates && this.isDuplicate(val)) {
return false;
}
let newItem = new LinkedListItem(val);
let currentItem = this._head;
if (!currentItem) {
return false;
}
else {
while (true) {
if (currentItem.value === previousItem) {
newItem.next = currentItem.next;
newItem.prev = currentItem;
currentItem.next = newItem;
if (newItem.next) {
newItem.next.prev = newItem;
}
else {
this._tail = newItem;
}
this._length++;
return true;
}
else {
if (currentItem.next) {
currentItem = currentItem.next;
}
else {
// can't locate previousItem
return false;
}
}
}
}
}
// Adds the element at the end of the linked list
append(val, checkDuplicates = false) {
if (checkDuplicates && this.isDuplicate(val)) {
return false;
}
let newItem = new LinkedListItem(val);
if (!this._tail) {
this._head = this._tail = newItem;
}
else {
this._tail.next = newItem;
newItem.prev = this._tail;
this._tail = newItem;
}
this._length++;
return true;
}
// Add the element at the beginning of the linked list
prepend(val, checkDuplicates = false) {
if (checkDuplicates && this.isDuplicate(val)) {
return false;
}
let newItem = new LinkedListItem(val);
if (!this._head) {
this._head = this._tail = newItem;
}
else {
newItem.next = this._head;
this._head.prev = newItem;
this._head = newItem;
}
this._length++;
return true;
}
remove(val) {
let currentItem = this._head;
if (!currentItem) {
return;
}
if (currentItem.value === val) {
this._head = currentItem.next;
this._head.prev = null;
currentItem.next = currentItem.prev = null;
this._length--;
return currentItem.value;
}
else {
while (true) {
if (currentItem.value === val) {
if (currentItem.next) { // special case for last element
currentItem.prev.next = currentItem.next;
currentItem.next.prev = currentItem.prev;
currentItem.next = currentItem.prev = null;
}
else {
currentItem.prev.next = null;
this._tail = currentItem.prev;
currentItem.next = currentItem.prev = null;
}
this._length--;
return currentItem.value;
}
else {
if (currentItem.next) {
currentItem = currentItem.next;
}
else {
return;
}
}
}
}
}
removeHead() {
let currentItem = this._head;
// empty list
if (!currentItem) {
return;
}
// single item list
if (!this._head.next) {
this._head = null;
this._tail = null;
// full list
}
else {
this._head.next.prev = null;
this._head = this._head.next;
currentItem.next = currentItem.prev = null;
}
this._length--;
return currentItem.value;
}
removeTail() {
let currentItem = this._tail;
// empty list
if (!currentItem) {
return;
}
// single item list
if (!this._tail.prev) {
this._head = null;
this._tail = null;
// full list
}
else {
this._tail.prev.next = null;
this._tail = this._tail.prev;
currentItem.next = currentItem.prev = null;
}
this._length--;
return currentItem.value;
}
first(num) {
let iter = this.iterator();
let result = [];
let n = Math.min(num, this.length);
for (let i = 0; i < n; i++) {
let val = iter.next();
result.push(val.value);
}
return result;
}
toArray() {
return [...this];
}
isDuplicate(val) {
let set = new Set(this.toArray());
return set.has(val);
}
}
exports.LinkedList = LinkedList;
class LinkedListItem {
constructor(val) {
this.value = val;
this.next = null;
this.prev = null;
}
}
exports.LinkedListItem = LinkedListItem;
//# sourceMappingURL=index.js.map