Add Elements at a Specific Index in a Linked List: Reassign head issue

Add Elements at a Specific Index in a Linked List

Hi,

I created my addAt() method. I changed the original code to my own code (ES6 class).
addAt(0, “any Data”) change the head node to Node.element = “any Data” but the first test fails…
On the client console I get some error:

TypeError: test.head is not a function

My code handle also negative index:
-0 : add element after the last node
-1 : insert the element to the last index
-2 : so on…
-length: insert the element to the head

But this behavior does not affect the test because easy to comment out and without negative index I also get the above error…

my code with negative index
class Node {
    constructor(value) {
        this.element = value;
        this.next = null;
    }
}

class LinkedList {
    constructor() {
        this.length = 0;
        this.head = null;
    }
    
    head() {
        return this.head;
    }
    
    size() {
        return this.length;
    }
    
    isEmpty() {
        return this.length
            ? false
            : true
        ;
    }
    
    add(element) {
        const addNode = new Node(element);
        let lastNode = this.getLastNode();
        lastNode 
            ? lastNode.next = addNode
            : this.head = addNode
        ;
        this.length ++;
    }
    
    addAt(index, element) {
        const length = this.length,
              negativ = length + index,
              addNode = new Node(element);
        ;
        if (index > length || index < (- length) || !(Number.isInteger(index))) return false;
        if (Object.is(index, 0) || negativ === 0) {
            // Insert to the head node
            addNode.next = this.head;
            this.head = addNode;
            this.length ++;
            return;
        }
        if (Object.is(index, -0)) index = length; // last node
        if (index < 0) index = negativ;
        const parentNode = this.getNodeAt(index -1);
        addNode.next = parentNode.next;
        parentNode.next = addNode;
        this.length ++;
    }
    
    remove(value) {
        let parentNode = this.getParentNode(value);
        if (!parentNode) return;
        if (parentNode === "head") {
            this.head = this.head.next;
        } else parentNode.next = parentNode.next.next;
        this.length --;
    }
    
    removeAt(index) {
        const length = this.length;
        const negativ = (length - 1) + index;
        if (index >= length || index <= (- length) || !(Number.isInteger(index))) return null;
        if (Object.is(index, 0) || negativ === 0) {
            const deletedNode = this.head.element;
            this.head = this.head.next;
            this.length --;
            return deletedNode;
        }
        if (Object.is(index, -0)) index = length - 1; // last node 
        if (index < 0) index = negativ;
        const parentNode = this.getNodeAt(index -1),
              deletedNode = parentNode.next
        ;
        parentNode.next = parentNode.next.next;
        this.length --;
        return deletedNode.element;
    }
    
    getParentNode(value, node = this.head, parentNode = this.head) {
        return !(this.head)
            ? null
            : this.head.element === value
                ? "head"
                : node.element === value
                    ? parentNode
                    : node.next
                        ? this.getParentNode(value, node.next, node)
                        : null
        ;
    }
    
    getLastNode(node = this.head) {
        return node 
            ? node.next
                ? this.getLastNode(node.next)
                : node
            : node
        ;
    }
    
    indexOf(value) {
        if (this.head.element === value) return 0;
        for (let i = 0, node = this.head; i < this.length; i ++, node = node.next) {
            if (node.element === value) return i;
        }
        return -1;
    }
    
    getNodeAt(index) {
        const length = this.length;
        if (index >= length || index <= (- length) || !(Number.isInteger(index))) return null;
        if (Object.is(index, 0)) return this.head;
        if (Object.is(index, -0)) return this.getLastNode();
        if (index < 0) index = (length - 1) + index;
        let node = this.head;
        for (let i = 0; i < index; i ++, node = node.next) {
        }
        return node;
    }
    
    elementAt(index) {
        const node = this.getNodeAt(index);
        return node 
            ? node.element
            : null
        ;
    }
}

const myList = new LinkedList();
myList.add("Csaba");
myList.add("Andi");
myList.add("Robin");
myList.add("Kriszta");
//myList.remove("Edina");
//myList.remove("Csaba");
//myList.remove("Robin");
//myList.remove("Andi");
//myList.remove("Andi");
//console.log(myList.isEmpty());
//console.log(myList.indexOf("Edina"));
//console.log(myList.elementAt(-4));
//console.log(myList.removeAt(0));
console.log(myList.addAt(0, "Kata"));
console.log(myList);
my code with positive index
class Node {
    constructor(value) {
        this.element = value;
        this.next = null;
    }
}

class LinkedList {
    constructor() {
        this.length = 0;
        this.head = null;
    }
    
    head() {
        return this.head;
    }
    
    size() {
        return this.length;
    }
    
    isEmpty() {
        return this.length
            ? false
            : true
        ;
    }
    
    add(element) {
        const addNode = new Node(element);
        let lastNode = this.getLastNode();
        lastNode 
            ? lastNode.next = addNode
            : this.head = addNode
        ;
        this.length ++;
    }
    
    addAt(index, element) {
        const length = this.length,
              negativ = length + index,
              addNode = new Node(element);
        ;
        if (index > length || index < /*(- length)*/ 0 || !(Number.isInteger(index))) return false;
        if (Object.is(index, 0) /*|| negativ === 0*/) {
            // Insert to the head node
            addNode.next = this.head;
            this.head = addNode;
            this.length ++;
            return;
        }
        if (Object.is(index, -0)) /*index = length*/ return false; // last node
        if (index < 0) /*index = negativ*/ return false;
        const parentNode = this.getNodeAt(index -1);
        addNode.next = parentNode.next;
        parentNode.next = addNode;
        this.length ++;
    }
    
    remove(value) {
        let parentNode = this.getParentNode(value);
        if (!parentNode) return;
        if (parentNode === "head") {
            this.head = this.head.next;
        } else parentNode.next = parentNode.next.next;
        this.length --;
    }
    
    removeAt(index) {
        const length = this.length;
        const negativ = (length - 1) + index;
        if (index >= length || index <= (- length) || !(Number.isInteger(index))) return null;
        if (Object.is(index, 0) || negativ === 0) {
            const deletedNode = this.head.element;
            this.head = this.head.next;
            this.length --;
            return deletedNode;
        }
        if (Object.is(index, -0)) index = length - 1; // last node 
        if (index < 0) index = negativ;
        const parentNode = this.getNodeAt(index -1),
              deletedNode = parentNode.next
        ;
        parentNode.next = parentNode.next.next;
        this.length --;
        return deletedNode.element;
    }
    
    getParentNode(value, node = this.head, parentNode = this.head) {
        return !(this.head)
            ? null
            : this.head.element === value
                ? "head"
                : node.element === value
                    ? parentNode
                    : node.next
                        ? this.getParentNode(value, node.next, node)
                        : null
        ;
    }
    
    getLastNode(node = this.head) {
        return node 
            ? node.next
                ? this.getLastNode(node.next)
                : node
            : node
        ;
    }
    
    indexOf(value) {
        if (this.head.element === value) return 0;
        for (let i = 0, node = this.head; i < this.length; i ++, node = node.next) {
            if (node.element === value) return i;
        }
        return -1;
    }
    
    getNodeAt(index) {
        const length = this.length;
        if (index >= length || index <= (- length) || !(Number.isInteger(index))) return null;
        if (Object.is(index, 0)) return this.head;
        if (Object.is(index, -0)) return this.getLastNode();
        if (index < 0) index = (length - 1) + index;
        let node = this.head;
        for (let i = 0; i < index; i ++, node = node.next) {
        }
        return node;
    }
    
    elementAt(index) {
        const node = this.getNodeAt(index);
        return node 
            ? node.element
            : null
        ;
    }
}

const myList = new LinkedList();
myList.add("Csaba");
myList.add("Andi");
myList.add("Robin");
myList.add("Kriszta");
//myList.remove("Edina");
//myList.remove("Csaba");
//myList.remove("Robin");
//myList.remove("Andi");
//myList.remove("Andi");
//console.log(myList.isEmpty());
//console.log(myList.indexOf("Edina"));
//console.log(myList.elementAt(-4));
//console.log(myList.removeAt(0));
console.log(myList.addAt(0, "Kata"));
console.log(myList);