UNPKG

ng2-bootstrap-base-modified

Version:

Native Angular Bootstrap Components Typeahead modified

259 lines (222 loc) 6.22 kB
export class LinkedList <T> { public length: number = 0; protected head: any; protected tail: any; protected current: any; protected asArray: T[] = []; protected getNode(position: number): any { if (this.length === 0 || position < 0 || position >= this.length) { throw new Error('Position is out of the list'); } let current = this.head; for (let index = 0; index < position; index++) { current = current.next; } return current; } protected createInternalArrayRepresentation(): void { let outArray: any[] = []; let current = this.head; while (current) { outArray.push(current.value); current = current.next; } this.asArray = outArray; } public get(position: number): T { if (this.length === 0 || position < 0 || position >= this.length) { return void 0; } let current = this.head; for (let index = 0; index < position; index++) { current = current.next; } return current.value; } public add(value: T, position: number = this.length): void { if (position < 0 || position > this.length) { throw new Error('Position is out of the list'); } let node = { value: value as any, next: undefined as any, previous: undefined as any }; if (this.length === 0) { this.head = node; this.tail = node; this.current = node; } else { if (position === 0) { // first node node.next = this.head; this.head.previous = node; this.head = node; } else if (position === this.length) { // last node this.tail.next = node; node.previous = this.tail; this.tail = node; } else { // node in middle let currentPreviousNode = this.getNode(position - 1); let currentNextNode = currentPreviousNode.next; currentPreviousNode.next = node; currentNextNode.previous = node; node.previous = currentPreviousNode; node.next = currentNextNode; } } this.length++; this.createInternalArrayRepresentation(); } public remove(position: number = 0): void { if (this.length === 0 || position < 0 || position >= this.length) { throw new Error('Position is out of the list'); } if (position === 0) { // first node this.head = this.head.next; if (this.head) { // there is no second node this.head.previous = undefined; } else { // there is no second node this.tail = undefined; } } else if (position === this.length - 1) { // last node this.tail = this.tail.previous; this.tail.next = undefined; } else { // middle node let removedNode = this.getNode(position); removedNode.next.previous = removedNode.previous; removedNode.previous.next = removedNode.next; } this.length--; this.createInternalArrayRepresentation(); } public set(position: number, value: T): void { if (this.length === 0 || position < 0 || position >= this.length) { throw new Error('Position is out of the list'); } let node = this.getNode(position); node.value = value; this.createInternalArrayRepresentation(); } public toArray(): T[] { return this.asArray; } public findAll(fn: any): any[] { let current = this.head; let result: any[] = []; for (let index = 0; index < this.length; index++) { if (fn(current.value, index)) { result.push({index, value: current.value}); } current = current.next; } return result; } // Array methods overriding start public push(...args: T[]): number { args.forEach((arg: any) => { this.add(arg); }); return this.length; } public pop(): T { if (this.length === 0) { return undefined; } const last = this.tail; this.remove(this.length - 1); return last.value; } public unshift(...args: T[]): number { args.reverse(); args.forEach((arg: any) => { this.add(arg, 0); }); return this.length; } public shift(): T { if (this.length === 0) { return undefined; } const lastItem = this.head.value; this.remove(); return lastItem; } public forEach(fn: any): void { let current = this.head; for (let index = 0; index < this.length; index++) { fn(current.value, index); current = current.next; } } public indexOf(value: T): number { let current = this.head; let position = 0; for (let index = 0; index < this.length; index++) { if (current.value === value) { position = index; break; } current = current.next; } return position; } public some(fn: any): boolean { let current = this.head; let result = false; while (current && !result) { if (fn(current.value)) { result = true; break; } current = current.next; } return result; } public every(fn: any): boolean { let current = this.head; let result = true; while (current && result) { if (!fn(current.value)) { result = false; } current = current.next; } return result; } public toString(): string { return '[Linked List]'; } public find(fn: any): T { let current = this.head; let result: T; for (let index = 0; index < this.length; index++) { if (fn(current.value, index)) { result = current.value; break; } current = current.next; } return result; } public findIndex(fn: any): number { let current = this.head; let result: number; for (let index = 0; index < this.length; index++) { if (fn(current.value, index)) { result = index; break; } current = current.next; } return result; } // Array methods overriding END }