const head = Symbol("head"); class LinkedListNode { constructor (data) { this.data = data; this.next = null; } } export class LinkedList { constructor () { this[head] = null; } add (data) { const newNode = new LinkedListNode(data); if (this[head] === null) { this[head] = newNode; } else { let current = this[head]; // Go to the end of the list while (current.next !== null) { current = current.next; } // On the last node, add the new node current.next = newNode; } } get (index) { if ( ! Number(index) < 0) { return undefined; } let current = this[head]; let i = 0; while ((current !== null) && (i < index)) { current = current.next; i++; } return current !== null ? current.data : undefined; } remove (index) { // Invalid index? if ((this[head] === null) || (index < 0)) { throw new RangeError(`Index ${index} does not exist in the list.`); } // Remove the first node if (index === 0) { const data = this[head].data; // Replace the head with the next node this[head] = this[head].next; return data; } let current = this[head]; let previous = null; let i = 0; while ((current !== null) && (i < index)) { // Save the current value previous = current; current = current.next; i++; } // Remove the node if found if (current !== null) { // skip over the node to "remove" it previous.next = current.next; return current.data; } throw new RangeError(`Index ${index} does not exist in the list.`); } *values () { let current = this[head]; while (current !== null) { yield current.data; current = current.next; } } [Symbol.iterator] () { return this.values(); } }