@dsinjs/linked-list
Version:
Linked List for your DS in JS
674 lines (670 loc) • 23.5 kB
JavaScript
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var linked_list_element_1 = require("./linked-list-element");
Object.defineProperty(exports, "LinkedListElement", { enumerable: true, get: function () { return linked_list_element_1.LinkedListElement; } });
var linked_list_main_1 = require("./linked-list-main");
Object.defineProperty(exports, "LinkedList", { enumerable: true, get: function () { return linked_list_main_1.LinkedList; } });
},{"./linked-list-element":2,"./linked-list-main":3}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LinkedListElement = void 0;
/**
* Linked list element class, contains data node and next pointer (element).
* @class LinkedListElement
* @public
* @example
* var elem = new LinkedListElement(15);
* var elem2 = new LinkedListElement(30, elem);
* console.log(elem2.next.data); // 15
*/
var LinkedListElement = /** @class */ (function () {
/**
* Standard constructor
* @param {T} data Value to be set
* @param {LinkedListElement<T>} next Optiona, Next element in the list.
*/
function LinkedListElement(data, next) {
if (next === void 0) { next = null; }
/**
* @property next
* Contains next element
* @type {LinkedListElement<T>}
* @public
*/
this.next = null;
this.data = data;
this.next = next;
}
/**
* Converts current element and all next elements in json format.
* @public
* @method toJSON
* @member
* @public
* @returns {LinkedListElementStruct<T>} valid json object.
* @example
* var elem = new LinkedListElement(30);
* var elem2 = new LinkedListElement(15, elem);
* elem2.toJSON(); // =>
* {
* "data": 15,
* "next": {
* "data": 30,
* "next": null
* }
* }
*/
LinkedListElement.prototype.toJSON = function () {
var data = this.data;
return {
data: (typeof data.toJSON === "function") ? data.toJSON() : data,
next: (this.next !== null) ? this.next.toJSON() : null
};
};
/**
* Converts current element and all next elements in string format.
* @public
* @method toString
* @member
* @public
* @returns {string} valid string.
* @example
* var elem = new LinkedListElement(30);
* var elem2 = new LinkedListElement(15, elem);
* elem2.toString(); // => 1530
*/
LinkedListElement.prototype.toString = function () {
var data = this.data;
return ((typeof data.toString === "function") ? data.toString() : String(data)) +
((this.next !== null) ? this.next.toString() : "");
};
return LinkedListElement;
}());
exports.LinkedListElement = LinkedListElement;
if (typeof module != "undefined") {
module.exports = { LinkedListElement: LinkedListElement };
}
if (typeof window != "undefined") {
window.DSinJS = window.DSinJS || {};
window.DSinJS.LinkedListElement = LinkedListElement;
}
},{}],3:[function(require,module,exports){
"use strict";
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LinkedList = void 0;
var linked_list_element_1 = require("./linked-list-element");
// if Symbol is not available in window
if (typeof window !== "undefined") {
if (typeof Symbol === "undefined") {
var win = window;
win.Symbol = {};
win.Symbol.iterator = "==iterator==";
}
}
/**
* Main Linked List class, contains start node and basically the whole list.
* @class LinkedList
* @public
* @example
* var lList = new LinkedList(10);
* lList.insert(20);
* lList.insert(30);
* lList.delete(30);
* lList.toArray(); // => [10,20]
*/
var LinkedList = /** @class */ (function () {
/**
* Standard constructor, accepts data values as LinkedListElement or T (actual data).
* @param {LinkedListElement<T> | T} startElem Starting element of your linked list.
*/
function LinkedList(startElem) {
/**
* @property _length
* Private member of linked list containing length of the list.
* @type {number}
* @private
* @member
* @property
*/
this._length = 1;
this._start = startElem;
if (!(this._start instanceof linked_list_element_1.LinkedListElement)) {
this._start = new linked_list_element_1.LinkedListElement(this._start);
}
}
Object.defineProperty(LinkedList.prototype, "length", {
/**
* @property length
* Readonly, Public member of linked list containing length of the list.
* @type {number}
* @public
* @member
* @property
* @readonly
* @example
* var lList = new LinkedList(15);
* lList.length; // => 1
*/
get: function () {
return this._length;
},
enumerable: false,
configurable: true
});
/**
* Inserts the given element at the end of the Linked List.
* @param {T} item New element to be inserted.
* @public
* @method insert
* @member
* @returns {LinkedListElement<T>} newly added element instance.
* @example
* var lList = new LinkedList(30);
* lList.insert(15);
* lList.insert(60);
*/
LinkedList.prototype.insert = function (item) {
if (item instanceof Array) {
if (item[0] instanceof linked_list_element_1.LinkedListElement) {
return this._insertLLElemArray(item);
}
else {
return this._InsertRawTypeItemArray(item);
}
}
else if (item instanceof linked_list_element_1.LinkedListElement) {
return this._insertLLElem(item);
}
else {
return this._InsertRawTypeItem(item);
}
};
LinkedList.prototype._InsertRawTypeItem = function (item) {
var prev = this._start;
var finalEl = prev;
while (prev !== null) {
finalEl = prev;
prev = prev.next;
}
finalEl.next = new linked_list_element_1.LinkedListElement(item);
this._length++;
return finalEl.next;
};
LinkedList.prototype._InsertRawTypeItemArray = function (item) {
var e_1, _a;
var first = new linked_list_element_1.LinkedListElement(item[0]);
var currElem = first;
item.splice(0, 1);
try {
for (var item_1 = __values(item), item_1_1 = item_1.next(); !item_1_1.done; item_1_1 = item_1.next()) {
var curr = item_1_1.value;
var nextElem = new linked_list_element_1.LinkedListElement(curr);
currElem.next = nextElem;
currElem = currElem.next;
this._length++;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (item_1_1 && !item_1_1.done && (_a = item_1.return)) _a.call(item_1);
}
finally { if (e_1) throw e_1.error; }
}
return this._insertLLElem(first);
};
LinkedList.prototype._insertLLElem = function (item) {
var prev = this._start;
var finalEl = prev;
while (prev !== null) {
finalEl = prev;
prev = prev.next;
}
finalEl.next = item;
this._length++;
return finalEl.next;
};
LinkedList.prototype._insertLLElemArray = function (item) {
var e_2, _a;
var first = item[0];
var currElem = first;
item.splice(0, 1);
try {
for (var item_2 = __values(item), item_2_1 = item_2.next(); !item_2_1.done; item_2_1 = item_2.next()) {
var curr = item_2_1.value;
var nextElem = curr;
currElem.next = nextElem;
currElem = currElem.next;
this._length++;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (item_2_1 && !item_2_1.done && (_a = item_2.return)) _a.call(item_2);
}
finally { if (e_2) throw e_2.error; }
}
return this._insertLLElem(first);
};
/**
* Pushes the given element at the end of the Linked List.
* @param {T} item New element to be pushed.
* @public
* @method push
* @member
* @returns {LinkedListElement<T>} newly added element instance.
* @example
* var elem = new LinkedList(30);
* elem.insert(15);
* elem.insert(60);
*/
LinkedList.prototype.push = function (item) {
return this.insert(item);
};
/**
* Deletes the given element if present and returns element instance otherwise returns null.
* @param {T} item New element to be pushed.
* @public
* @method delete
* @member
* @returns {LinkedListElement<T> | null} Returns deleted elemnt or null.
* @example
* var elem = new LinkedList(30);
* elem.insert(15);
* elem.insert(60);
* elem.delete(15); // => { data: 15, next: null }
* elem.delete(50); // null
*/
LinkedList.prototype.delete = function (item) {
var curr = this._start;
var prev = this._start;
while (curr !== null) {
if (item === curr.data) {
break;
}
prev = curr;
curr = curr.next;
}
if (prev && curr) {
prev.next = curr.next;
curr.next = null;
this._length--;
}
return curr;
};
/**
* Removes last element in the linked list and returns it.
* @public
* @method pop
* @member
* @returns {LinkedListElement<T> | null} Returns deleted elemnt or null.
* @example
* var elem = new LinkedList(30);
* elem.insert(15);
* elem.insert(60);
* elem.pop(15); // => { data: 15, next: null }
* elem.pop(60); // null
*/
LinkedList.prototype.pop = function () {
var curr = this._start;
var prev = this._start;
while (curr.next !== null) {
prev = curr;
curr = curr.next;
}
prev.next = null;
if (curr === this._start) {
return null;
}
this._length--;
return curr;
};
/**
* Checks for given item in the entire list and returns true if available.
* @param {T} item New element to be checked.
* @public
* @method has
* @member
* @returns {boolean} newly added element instance.
* @example
* var elem = new LinkedList(30);
* elem.insert(15);
* elem.insert(60);
* elem.has(15); // true
* elem.has(50); // false
*/
LinkedList.prototype.has = function (item) {
var curr = this._start;
while (curr !== null) {
if (curr.data === item) {
return true;
}
curr = curr.next;
}
return false;
};
/**
* Traverses the whole list and calls given callback function for each element.
* @param {{(elem :LinkedListElement<T>, index: number) => boolean}} callback Callback function to be called
* for each element instance. If function returns false for any value then it stops traversal.
* @public
* @method traverse
* @member
* @returns {void} Returns undefined.
* @example
* var dataPrinter = (el) => { console.log(el.data); };
* var lList = new LinkedList(15);
* lList.insert(30);
* lList.traverse(dataPrinter); // => 15...20
*/
LinkedList.prototype.traverse = function (callback) {
var prev = this._start;
var finalEl = prev;
var counter = 0;
while (prev !== null) {
var retVal = callback(prev, counter);
if (!retVal) {
break;
}
finalEl = prev;
prev = prev.next;
counter++;
}
};
/**
* Returns an iterable of key, value pairs for element in the Linked List.
* @public
* @method entries
* @member
* @returns {IterableIterator<[number, T]>} Iterables of index keys and values.
* @example
* var lList = LinkedList.fromArray([1, 2, 3]);
* for (const [index, item] of lList.entries()) {
* console.log(index, item); // => 0 1...1 2...2 3
* }
*/
LinkedList.prototype.entries = function () {
return this.toArray().entries();
};
/* [Symbol.iterator](): any {
let curr: LinkedListElement<T> | null | undefined = this._start;
let isFirst = true;
const _this: LinkedList<T> = this;
return {
[Symbol.iterator]: this[Symbol.iterator].bind(this),
next: (...args: any[]) => {
curr = curr?.next;
let done = (isFirst) ? false : (curr) ? false : true;
let value = (done) ? void 0 : (curr as LinkedListElement<T>).data;
if (isFirst) {
value = _this._start.data;
done = false;
isFirst = false;
}
return {
done: done, value: value
};
}
}
} */
/**
* Standard Iterator.
* @public
* @method [Symbol.iterator]
* @member
* @returns {IterableIterator<T>} Iterables of element values.
* @example
* var lList = LinkedList.fromArray([1, 2, 3]);
* for (const item of lList.entries()) {
* console.log(item); // => 1...2...3
* }
*/
LinkedList.prototype[Symbol.iterator] = function () {
return this.toArray()[Symbol.iterator]();
};
/**
* Traverses the whole list and calls given callback function for each element.
* @param {{(elem :LinkedListElement<T>, index: number) => boolean}} callback Callback function to be called
* for each element instance. If function returns false for any value then it stops traversal.
* @public
* @method each
* @member
* @returns {void} Returns undefined.
* @example
* var dataPrinter = (el) => { console.log(el.data); };
* var lList = new LinkedList(15);
* lList.insert(30);
* lList.each(dataPrinter); // => 15...20
*/
LinkedList.prototype.each = function (callback) {
return this.traverse(callback);
};
/**
* Traverses the whole list and calls given callback function for each element.
* @param {{(elem :LinkedListElement<T>, index: number) => boolean}} callback Callback function to be called
* for each element instance. If function returns false for any value then it stops traversal.
* @public
* @method forEach
* @member
* @returns {void} Returns undefined.
* @example
* var dataPrinter = (el) => { console.log(el.data); };
* var lList = new LinkedList(15);
* lList.insert(30);
* lList.forEach(dataPrinter); // => 15...20
*/
LinkedList.prototype.forEach = function (callback) {
return this.traverse(callback);
};
/**
* Maps current linked list values to a new linked list with modifying the values using given callback function.
* Uses BFS.
* @param {{(value: T) => T}} callback callback function for value modifier.
* @method map
* @member
* @public
* @returns {LinkedList<T>} A newly mapped linked list.
* @example
* var lList = LinkedList.fromArray([10, 20, 30, 40]);
* var lList2 = lList.map(n => n * 2);
* var arr2 = lList2.toArray(); // [20, 40, 60, 80]
*/
LinkedList.prototype.map = function (mappingFnc) {
var nLink = new LinkedList(mappingFnc(this._start.data));
var curr = this._start.next;
var newCurr = nLink._start;
while (curr !== null) {
newCurr.next = new linked_list_element_1.LinkedListElement(mappingFnc(curr.data));
nLink._length++;
curr = curr.next;
newCurr = newCurr.next;
}
return nLink;
};
/**
* Filters each item based on given filter function and returns new linked list.
* If no value is filtered then returns null.
* @param {{(value: T) => boolean}} filterFnc callback function for filtering purpose.
* @method filter
* @member
* @public
* @returns {LinkedList<T> | null} New filtered instance of tree or null.
* @example
* var lList = LinkedList.fromArray([10, 20, 30, 40]);
* var lList2 = lList.filter(n => !!(n % 4 === 0));
* var arr2 = lList2.toArray(); // [20, 40]
*/
LinkedList.prototype.filter = function (filterFnc) {
var firstItem = null;
var curr = this._start;
while (firstItem === null) {
if (curr) {
if (filterFnc(curr.data)) {
firstItem = curr.data;
}
curr = curr.next;
}
else {
break;
}
}
if (firstItem === null) {
return null;
}
var nList = new LinkedList(firstItem);
var newCurr = nList._start;
while (curr !== null && curr !== void 0) {
if (filterFnc(curr.data)) {
newCurr.next = new linked_list_element_1.LinkedListElement(curr.data);
nList._length++;
}
curr = curr.next;
}
return nList;
};
/**
* Reduces each element value using reduceFunction and returns final value.
* @param {(next: T2, value: T, index: number, tree: BTree<T>) => T2} reduceFnc callback function
* for reducing each node value to a final value.
* @param {T2} initialValue Optional, Accumulator/Initial value.
* @method reduce<T2>
* @member
* @public
* @returns {T2} Returns reduced value
* @example
* var lList = LinkedList.fromArray([10, 20, 30, 40]);
* var sum = lList.reduce((acc, elem) => acc + elem); // => 100
*/
LinkedList.prototype.reduce = function (reduceFnc, initialValue) {
var _this = this;
if (initialValue === void 0) { initialValue = 0; }
var curr = initialValue;
this.traverse(function (elem, index) {
curr = reduceFnc(curr, elem.data, index, _this);
return true;
});
return curr;
};
/**
* Returns element at given location.
* @param {number} index Index to find the element.
* @public
* @method get
* @member
* @returns {{T | null}} Returns element found at given element, if its not reachable returns null.
* @example
* var lList = new LinkedList(15);
* lList.insert(30);
* lList.insert(45);
* lList.get(2); // => 45
*/
LinkedList.prototype.get = function (index) {
var prev = this._start;
var counter = 0;
var retElem = null;
while (prev !== null) {
if (index === counter) {
retElem = prev.data;
break;
}
prev = prev.next;
counter++;
}
return retElem;
};
/**
* Returns string form of the linked list.
* @public
* @method toString
* @member
* @returns {string} Returns string form of the linked list.
* @example
* var lList = new LinkedList(1);
* lList.push(2);
* lList.toString(); // => "12"
*/
LinkedList.prototype.toString = function () {
return this._start.toString();
};
/**
* Returns javascript root object form of the linked list.
* @public
* @method toJSON
* @member
* @returns {LinkedListElementStruct<T>} Returns javascript root object form of the linked list.
* @example
* var lList = new LinkedList(1);
* lList.push(2);
* lList.toJSON(); // => { data: 1, next: { data: 2, next: null } }
*/
LinkedList.prototype.toJSON = function () {
return this._start.toJSON();
};
/**
* Returns array form of the linked list.
* @public
* @method toArray
* @member
* @returns {T[]} Returns array form of the linked list.
* @example
* var lList = new LinkedList(1);
* lList.push(2);
* lList.push(3);
* lList.toArray(); // => [1, 2, 3]
*/
LinkedList.prototype.toArray = function () {
var retArr = [];
var curr = this._start;
while (curr !== null) {
retArr.push(curr.data);
curr = curr.next;
}
return retArr;
};
/**
* A static method, Creates a Linked List instance from given array.
* @param {T[]} array Array of elements.
* @public
* @method fromArray
* @static
* @returns {LinkedList<T>} Returns new linked list instance with all elements in array.
* @example
* var lList = LinkedList.fromArray([1, 2, 3]);
* lList.length; // => 3
*/
LinkedList.fromArray = function (array) {
var currIndex = 1;
var lList = new LinkedList(array[0]);
var curr = lList._start;
while (currIndex !== array.length) {
curr.next = new linked_list_element_1.LinkedListElement(array[currIndex]);
curr = curr.next;
currIndex++;
lList._length++;
}
return lList;
};
return LinkedList;
}());
exports.LinkedList = LinkedList;
if (typeof module != "undefined") {
module.exports = { LinkedListElement: linked_list_element_1.LinkedListElement, LinkedList: LinkedList };
}
if (typeof window != "undefined") {
window.DSinJS = window.DSinJS || {};
window.DSinJS.LinkedList = LinkedList;
}
},{"./linked-list-element":2}]},{},[1]);