No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

13 Días
19 Hrs
29 Min
11 Seg

Agregar nodos a la lista

17/29
Recursos

Aportes 89

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

🗒 Aporte para la clase

Algo que me ayudo bastante a la hora de entender esta clase fue que estamos jugando bastante con la referencia de JavaScript. Recuerda mantener la idea de que no estamos guardando los valores de los objetos en sí, si no el lugar [referencia] de donde se encuentran en el memory heap.


El memory Heap es donde se guardan todos los objetos, debido a que los objetos necesitan una mayor cantidad de memoria a diferencia que los números, cadenas o boleanos, la desventaja es que el memory heap es lento por lo cual se necesita dar una ubicación de donde se está guardado. Si deseas saber más acerca de este tema puedes revisar este video creado por el profesor del curso de fundamentos de javascript


😉 Mi explicación del código según a lo que entendí

class MySinglyLinkedList {
  constructor(value) {
    // creamos el inicio de nuestro SinglyLinkedList
    this.head = {
      value,
      next: null,
    };

    // Aqui sucede la magia ✨
    // Todo lo que modifiquemos en los atributos de tail
    // se modificará en la estructura inicial
    // por la RERENCIA!
    this.tail = this.head;

    this.length = 1;
  }

  append(value) {
    // aquí estamos creando un nuevo nodo
    const newNode = new Node(value);

    // Como mencionamos anteriormente
    // si modificamos la cola por la REFERENCIA
    // se modificará la estructura inicial! 🖊
    this.tail.next = newNode;
    // Pero aun tail sigue apuntando a la CABEZA
    // de la estructura inicial entonces es momento
    // de apuntar al nuevo nodo creado para que posteriormente
    // podamos agregar más nodos! 🚀
    this.tail = newNode;
    // Finalmente aumentamos el tamaño definido de
    // nuestra estructura 👨‍🔧
    this.length++;

    return this;
  }

💚 Cualquier correción o comentario es bienvenido!

Creo que para esta clase es importante entender también que cuando generamos un objeto en JS y luego igualamos otra variable a la variable anterior lo que hacemos es que apuntamos desde las dos variables al mismo espacio en memoria, por eso cuando decimos:

this.head = new Node(value)
this.tail = this.head

Cada vez que hagamos un cambio en this.tail ese cambio también va a afectar a this.head, por eso en el método append, cuando le decimos:

this.tail.next = newNode

A su vez también cambiamos el valor this.head.next, luego hacemos que this.tail apunte al espacio en memoria de newNode diciéndole:

this.tail = newNode 

La próxima vez que cambiemos this.tail ya no va a afectar a this.head.
Gracias a esto es que podemos aplicar los métodos append y prepend de esta manera, esto lo podemos probar haciendo en el constructor de SinglyLinkedList lo siguiente:

this.head = {
  value: value,
  next: null
}
this.tail = {...this.head}

De esa manera this.tail ya no estará apuntando al espacio en memoria que ocupa this.head sino que pasará a ocupar uno nuevo, y los cambios que se hagan en this.tail no afectaran a this.head por ende el método de append la primera vez que se llama no hará que mute this.head. Esto es un problema porque no es el comportamiento que queremos, pero es importante que entendamos que no siempre la mutabilidad en JS es mala (aunque la querramos evitar en la mayoría de los casos) y qué podemos sacarle provecho sabiéndola utilizar. La otra opción es evitar que los objetos muten y tener control sobre lo que ocurre tanto en this.tail como en this.head.

Un poco de ayuda grafica, saludos 😃
Al inicio:

Intermedio :

Es simple, de hecho me recuerda mucho a los callbacks hell jajaja, simplemente se trata de crear un nuevo nodo y meterlo dentro del next del nodo que está actualmente como la cola.
.
Y para la cabeza, lo único que hicimos fue, agarrar la cabeza actual, que ya contenía toda nuestra lista de nodos hijos, y meterla en una nueva cabeza, de esa forma pudimos hacer un prepend ^^

La logica es parecida al callback hell, es ir anidando punteros a direcciones en memoria de cada uno de los nuevos nodos, esto a final queda una estractura de cuando anidamos callbacks.
.
Para practicar la logica de programacion y que se les sea mas facil implementar en el codigo lo que se nos pide, yo les recomiendo hacer algo de pseudo codigo.

  • Escribir literal el paso a paso
  • dibujar ayuda tambien
  • la tecnica del patito de hule suele funcionar.

En lo personal yo hago un dibujo y escribo lo que deberia de hacer paso a paso. Esa es la manera en que practico mi logica. Te la recomiendo quizás a ti tambein te sirva como me sirve a mi

Reto insert:

TIP: Para comentar todas las líneas juntas:

simplemente aprietan Ctrl + K + C.

TIP: Para quitar el comment a todas las líneas juntas:

simplemente aprietan Ctrl + K + U.
Saludos!!

👩‍💻👨‍💻 Código de la clase

// 1 --> 2 --> 3 --> 4 --> 5 --> null

// let singlyLinkedLis = {
//   head: {
//     value: 1,
//     next: {
//       value: 2,
//       next: {
//         value: 3,
//         next: {
//           value: 4,
//           next: null
//         }
//       }
//     }
//   }
// }

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class MySinglyLinkedList {
  constructor(value) {
    this.head = {
      value,
      next: null
    }
    this.tail = this.head;

    this.length = 1;
  }

  append(value) {
    const newNode = new Node(value);

    this.tail.next = newNode;
    this.tail = newNode;
    this.length++;

    return this;
  }

  prepend(value) {
    const newNode = new Node(value);
    newNode.next = this.head;
    this.head = newNode;
    this.length++;

    return this;
  }
}

let myLikedList = new MySinglyLinkedList(1);
console.log(myLikedList);
console.log(myLikedList.append(2));
console.log(myLikedList.prepend(0));

buen dia, cuando se agrega un nuevo nodo en la lista con el metodo insert con un solo parametro, se genera un undefine como lo de la imagen.

insert(index, value) {
    //add a node "outside" the list (=> invalid)
    if(index < 0 || index > this.length) { 
      return null;
    } else if(index === 0) {
      //add a node to the beginning of the list
      return this.prepend(value);
    } else if(index === this.length) { //>=
      //add a node to the end of the list
      return this.append(value)
    } else {
      const newNode = new Node(value);
      const firstPointer = this.getTheIndex(index - 1);
      const holdingPointer = firstPointer.next;
      firstPointer.next = newNode;
      newNode.next = holdingPointer;
      this.length++;
  
      return this;
    }
  }
  getTheIndex(index) {
    let counter = 0;
    let currentNode = this.head;

    while(counter !== index) {
      currentNode = currentNode.next;
      counter++;
    }

    return currentNode;
  }
Hice este pequeño ejemplo visual para mostrar cómo va cambiando la Singly Link List a medida que agregamos nodos con append y prepend ✨. ![](https://i.imgur.com/RCh0WtF.png)

De verdad le aplaudo a este profesor. De lo mejor que hay en platzi. Joya!

No dejen ir al gran Diego De Granda

Callback Hell puro.

* `head -> -1 -> 0 -> 1 -> null` Copio y pego mi codigo pero se ve mal? head -> -1 -> 0 -> 1 -> null Alguien sabe como debo insertarlo? Ya probe con inline code format y tambien insert block code
### Lo que hace el método `prepend`: 1. **Crear un nuevo nodo:** `const newNode = new Node(value);` Esto crea un nuevo nodo con el valor que pasamos como parámetro. Este nodo aún no está conectado a la lista, simplemente lo hemos creado. 2. **Apuntar el nuevo nodo al antiguo** `head`**:** `newNode.next = this.head;` Aquí, estamos haciendo que el `next` del nuevo nodo apunte a lo que era el antiguo `head`. Es como decirle al nuevo nodo: "El que estaba primero en la lista ahora viene después de ti." 3. **Actualizar el** `head`**:** `this.head = newNode;` Ahora, cambiamos el `head` de la lista para que apunte al nuevo nodo, ya que este nuevo nodo será el primero de la lista. 4. **Aumentar el tamaño de la lista:** `this.lenght++;` Simplemente incrementamos el contador de elementos en la lista. 5. **Retornar la lista actualizada:** `return this;` Devolvemos la lista actualizada para poder seguir encadenando operaciones si es necesario. ### Ejemplo práctico: Supongamos que tienes la lista enlazada que inicialmente tiene solo un valor: * `head -> 1 -> null` Después de hacer `mySinglyLinkedList.prepend(0)`, lo que sucede es: 1. Se crea un nuevo nodo con valor `0`. 2. Este nuevo nodo apunta a lo que era el `head` anterior (el nodo con valor `1`). 3. El `head` ahora apunta a este nuevo nodo con valor `0`. El resultado será: * `head -> 0 -> 1 -> null` Si luego haces `mySinglyLinkedList.prepend(-1)`, obtendrás: * `head -> -1 -> 0 -> 1 -> null` ### Visualización de los pasos: 1. Lista original:`head -> 1 ->` null 2. Después de `prepend(0)`:`head -> 0 -> 1 ->` null 3. Después de `prepend(-1)`:`head -> -1 -> 0 -> 1 ->` null Cada vez que usas `prepend`, el nuevo valor se coloca al principio de la lista, desplazando al `head` anterior.
No tengo niebla más remota idea de lo que se hace en esta clase!!! JavaScript es realmente un dolor de cabeza. para que es esto? en dónde utilizaré esto?
```js class Node{ constructor(value){ this.value = value; this.next = null; } } class LinkedList{ constructor(value){ this.head ={ value: value, next: null, }; this.tail = this.head; this.length = 1; } append(value){ const newNode = new Node(value); this.tail.next = newNode; this.tail = newNode; this.length++; return this; } prepend(value){ const newNode = new Node(value); newNode.next = this.head.next; this.head.next = newNode; if(this.length === 1){ this.tail = newNode; } this.length++; return this; } insert(index, value){ if(index < 0 || index > this.length){ throw new Error("Index out of bounds"); } if(index === 0){ return this.prepend(value); } if(index === this.length){ return this.append(value); } const newNode = new Node(value); const currentNode = this.traverseToIndex(index - 1); newNode.next = currentNode.next; currentNode.next = newNode; this.length++; return this; } } let myLinkedList = new LinkedList(1); ```
Compartiré por aquí mi implementación del método insert ✨. ![](https://i.imgur.com/AwrgJgT.png)
No he visto la clase, creo que esto podria funcionar, sin embargo debido a la mutabilidad de los objetos , no estoy seguro de estar reassignando correctamente la cola : ¡¿ustedes que piensan? ```js append(value){// puts a new node on the tail if (this.length===1){ this.tail=node(value) this.head.next=this.tail }else{ let formerTail={...this.tail} formerTail.next=this.tail this.tail=node(value) } this.length++ } ```

Después de entender la solución de append (me tomó tiempo. Mucho. Tiempo.), conseguí generar el prepend por mi cuenta 🥲

Según entendí que debía de funcionar, esta fue mi solución (antes de la clase): ```js append(value) { const newValue = new Node(value); this.tail.next = newValue; this.tail = newValue; this.length++; return newValue; } ```

Append y Prepend
Considerando el caso en que la LinkedList esté vacía.

append(value) {
    const newNode = new Node(value);

    if (!this.head) {
      this.head = newNode;
      this.tail = newNode;
      this.length++;
      return this;
    }

    this.tail.next = newNode;
    this.tail = newNode;
    this.length++;
    return this;
  }

  prepend(value) {
    const newNode = new Node(value);

    if (!this.head) {
      this.head = newNode;
      this.tail = newNode;
      this.length++;
      return this;
    }

    newNode.next = this.head;
    this.head = newNode;
    this.length++;
    return this;
  }
insert($_item, $_position) {
    const node = new ENode($_item);
    let pointer = this.head;

    if($_position > this.length){
      throw new Error("List index out of bounds")
    }

    if($_position == 0){
      this.addFirst($_item); // prepend
      return;
    }
    
    while ($_position > 1) {
      pointer = pointer.next;
      $_position--;
    }

    node.next = pointer.next
    pointer.next = node;
    this.length++
  }

en esta clase no entiendo por completo y es que no se para que puede servir esta estructura algun ejemplo por que solo veo en consola

Método prepend


class MySinglyLinkedList {

    constructor(value) {

        this.head = {

            value: value,
            next: null

        }

        this.tail = this.head;

        this.length = 1;

    };

    prepend(value) {

        const newNode = new Node(value);

        newNode.next = this.head;

        this.head = newNode;

        this.length++;

        return this;

    };

};

class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}

class MySinglyLinkedList {
constructor(value) {
this.head = {
value: value,
next: null,
}
this.tail = this.head;

    this.length = 1;
}
append(value) {
    const newNode = new Node(value);

    this.tail.next = newNode;
    this.tail = newNode;
    this.length++;

    return this;
}

prepend(value) {
    const newNode = new Node(value);

    newNode.next = this.head;
    this.head = newNode;

    this.length++;
    
    return this;
}

}

let myLinkedList = new MySinglyLinkedList(1);

aqui con micho esfuerzo hice un metodo para agregar un nodo en cualquier posicion indicada

    add (index,value) {
        const newNode = new Node(value);
        let actualNode = this.head
        let previusNode = this.head
        for (let i = 1; i < index; i++) {
            if (i == index - 1) {
                previusNode = actualNode
            }
            
            if (actualNode.next) {
                actualNode = actualNode.next
            } else {
                return
            }
        }
        
        newNode.next = actualNode
        previusNode.next = newNode
        this.length++
        return this;
    }

Me recordó a la clase de punteros en C, en el 2009. No solo variables sino espacios de memoria.
🤯🤯

La clase es muy clara pero considero que el profesor debió haber echo un pequeño recordatorio de que el tail apunta a la referencia del último valor del linkedList, esta es la razón por que al reasignar el next del tail se modifica el valor en el linkedList.

Sin esto claro, el código funciona bien pero no queda claro porque y creo que puede confundir bastante, pero el tema de la clase es super claro y se entiende perfecto.

Para cualquiera que tenga esta duda y quiera entender en detalle como funcionan los valores por referencia les dejo este articulo que deja super claro el tema.

https://www.javascripttutorial.net/javascript-primitive-vs-reference-values/

addNode(value){
    let node = new Node(value);
    this.tail.next=node;
    this.tail = node;
  }

Creo que aqui se debio hacer mas mencion a la diferencia entre pasar valores por Referencia y Valor, ya que es la base para entender los metodos de Append y prepend

Cuando usamos palabras reservadas o metodos, entiendo que todo nace del súper prototipo, pero como es que esta construido el super prototipo. Estamos construyendo estas estructuras gracias a la capa de abstracción anterior pero tarde o temprano llegamos al super prototype, ¿Como esta construido el super prototype?

Para agregar en cualquier lado:

insert(value,pos){
        if(pos == 0){
            this.prepend(value);
        }else if(pos >= this.length - 1){
            this.append(value);
        }else{
            const node = new Node(value);
            const datatoInsert = this.explore(this.head,pos);
            node.next = datatoInsert.next;
            datatoInsert.next = node;
            this.length++;
        }
    }

    explore(nodeActual,limit){
        if(limit == 0){
            return nodeActual;
        }else{
            return this.explore(nodeActual.next,limit - 1);
        }
    }

El prepend:

prepend(value){
        const node = new Node(value);
        node.next = this.head;
        this.head = node;
        this.length++;
        
    }

Hice este metodo para imprimir los datos en formato de linked list. Una ayuda para entender mejor.

print() {
    let result = "";
    let currentNode = this.head;
    while (currentNode) {
      if (!currentNode.next) {
        result += ` ${currentNode.data}`;
      } else {
        result += ` ${currentNode.data} -->`;
      }
      currentNode = currentNode.next;
    }
    return result;
  }

Yo hice el Prepend un poco diferente pero funciona igual:

	prepend(value) {
		const body = this.head;
		const newNode = new Nodo(value);
		this.head = newNode;
		this.head.next = body;
		this.length++;

		return this;
	}

mi ejercicio esta en python pero creo que para las personas que esten haciendo este curso por la forma que crea las estructuras de datos le servira o vera otra manera de realizarlo.

<
class Node:
    
    def __init__(self,data) -> None:
        self.data = data
        self.next = None


class LinkendList:

    def __init__(self) -> None:
        self.head = None
        self.tail = self.head
        self.size = 0
    
    
    def insert(self,data):
        """insert method
            This method allow us add a new item at the end of the LinkedList.

        Args:
            data (_type_): value that will be take the next node to add.
        """
        
        new_item = Node(data)

        if not self.head:

            self.head = new_item
            self.tail = self.head
        elif self.size == 1:

            self.tail = new_item
            self.head.next = self.tail          

        else:
            current = self.tail
            current.next = new_item
            self.tail = current.next
        



new_linkedList = LinkendList()
new_linkedList.insert(23)
new_linkedList.insert(40)
new_linkedList.insert(20)

current = new_linkedList.head
while current :
    print(current.data,end=' -> ')
    current = current.next> 
class MyNode {
  value: String|Number|Array<any>
  next: any
  constructor(value: String|Number|Array<any>) {
    this.value = value
    this.next = null
  }
}

// Singly linked list
class MyLinkList {
  public head: MyNode
  public tail: MyNode
  public length: number
  constructor(value: String|Number|Array<any>) {
    this.head = new MyNode(value)
    this.tail = this.head
    this.length = 1;
  }

  append(value: String|Number|Array<any>) {
    const newNode = new MyNode(value)
    this.tail.next = newNode
    this.tail = newNode
    this.length++
    return this
  }

  preppend(value: String|Number|Array<any>) {
    const newNode = new MyNode(value)
    newNode.next = this.head
    this.head = newNode
    this.length++
    return this
  }
}

Aproveche el curso para escribir mis primeras líneas de TypeScript lo cual recomiendo, lo hace ligeramente más retador mientras aprendes algo extra. URL TypeScript playground y la documentación de TypeScript

Es excelente, es la misma logica que se usa para el patron de una cadena de responzabilidad. https://refactoring.guru/es/design-patterns/chain-of-responsibility

Así lo hice yo

newNode(value){
        this.tail.next = new Node(value);
        this.tail = this.tail.next;
        this.length++;
    }

Mi solucion a los retos con la implementacion de un metodo que imprime a la singly linked list como si fuera un array normal

class Node {
  constructor(value, next = null) {
    this.value = value;
    this.next = next;
  }
}

class SinglyLinkedList {
  constructor(value) {
    this.head = new Node(value);
    this.tail = this.head;
    this.length = 1;
  }
  append(value) {
    const newNode = new Node(value);
    this.tail.next = newNode;
    this.tail = newNode;
    this.length++;
  }
  prepend(value) {
    this.head = new Node(value, this.head);
    this.length++;
  }
  print() {
    let current = this.head;
    let linkedList = [];
    while (current != null) {
      linkedList.push(current.value);
      current = current.next;
    }
    console.log(linkedList);
  }
}

Cree el método a través de una función recursiva

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class SinglyLinkedList {
  constructor(value) {
    this.head = { value, next: null };
    this.tail = new Node(value);
    this.length = 1;
  }

  _assignNext(instance, newNode) {
    if (instance.next === null) {
      instance.next = newNode;
      return;
    }
    this._assignNext(instance.next, newNode);
  }

  append(value) {
    this._assignNext(this.head, new Node(value));
    this.length++;
  }
}

const pageNavigator = new SinglyLinkedList("htps://platzi.com");
console.log(pageNavigator.length, pageNavigator.head);

pageNavigator.append("htps://digital.dev.greatminds.dev/");
console.log(pageNavigator.length, pageNavigator.head);

pageNavigator.append("htp://localhost:3000/");
console.log(pageNavigator.length, pageNavigator.head);

Este es mi aporte a la comunidad

<code> 
function Nodo(value){
    this.value = value,
    this.next = null
}

class SingleLinkedList {
    constructor(value) {
        this.head = {
        value : value,
        next : null
    }
    this.tail = this.head
    this.length = 1
    }
****}

Me acuerdo cuando en la Universidad alcance a ver este tema pero con Java, la verdad esto de las listas es muy divertido, llámenme loco jajajajja

Mi solución al insertar implementado en TypeScript:

  insert(value: T, position: number): void {
    if (position >= this._length) return this.append(value);
    if (position <= 0) return this.prepend(value);

    const node = new Node(value);
    let current = this.head;
    let previous = this.head;
    for (let i = 0; i < position; i++) {
      previous = current;
      current = current!.next;
    }
    previous!.next = node;
    node.next = current;
    this._length++;
  }

Esta es la alternativa usando recursividad (es menos óptima que la del profe porque él usa el tail como acceso directo y no tiene que recorrer la estructura completa) pero la recursividad es algo que se pide mucho en pruebas técnicas para Amazon, google, etc así que nunca está de mas practicarla

append(value,current){
        //console.log(!current)
        if(!current){
            current=this.head
        }
        if(current.next==null){
            let nodo=new Nodo(value)
            current.next=nodo
            this.tail=nodo
        }else{
            this.append(value,current.next)
        }
    }

Les comparto mi solución a la implementación del método insert(value, position). Criterios de aceptación que definí para una lista de N nodos:

  • podrá insertar al inicio y al final de la lista
  • position debe ser > 0 y <= this.length +1
  • si position = 1 entonces hace un prepend(value)
  • si position = this.length +1 entonces hace un append(value)
  • debe poder insertar un nodo en cualquier posición dentro de la lista.
    insert(value, position) {
        if(position > 0 && position <= this.length +1) {
            if(position == 1) {
                this.prepend(value);
                return this;
            }
            if(position == this.length +1) {
                this.append(value);
                return this;
            }
            let newNode = new MyNode(value);
            let nextNode = this.head;
                for(let i = 1; i < position -1; i++) {
                nextNode = nextNode.next;
            }
            let tempNode = nextNode.next;
            nextNode.next = newNode;
            newNode.next = tempNode;
            this.length++;
            return this;
        }
        return undefined;
    }
<code> 
    public getNode(indexValue : number) : Node | null{
        let currentNode : Node | null = this.head.next
        if (currentNode){
            while(currentNode.value !== indexValue){
                let nextNode : Node | null = currentNode.next
                if (nextNode){
                    currentNode = nextNode
                }else{
                    return null
                }
            }
        }else{
            return null
        }
        return currentNode
    }
    public insertNodeAfter(previousNodeValue : number, value : number) : void{
        let newNode : Node = new Node(value)
        let previousNode : Node | null = this.getNode(previousNodeValue)
        if (previousNode){
            let nodeToReplace : Node | null = previousNode.next
            previousNode.next = newNode
            newNode.next = nodeToReplace
            this.length = this.length + 1            
        }
    }

<code>


esto me funciona

My code of append function

   append(value){
     if (this.length = 1) {
       this.head.next = new Node(value);
       this.tail = this.head.next;
       this.length++;
      } else if (this.length > 1) {
        let current = this.head;
        while ( current.next ) {
          current = current.next;
        }
        current.next = new Node(value)
        this.tail = current.next;
        this.length++;
      }

Despues de un buen rato consegui resolver el reto
Ojo: Este codigo va dentro de la clase de mySingleLinkedList

insert(value)
  {
    if(this.length > 1)
    {
      const div = Math.round(this.length/2)
      const newNode = new Node(value)
      this.view(this.head,div,newNode)
      return this
    }
    this.append(value)
  }

// No sabia que nombre ponerle a esta funcion y como la inicie view por esa era su funcion antes
  view(node, veces, newNode)
  {
    veces--
    if(veces === 0)
    {
      newNode.next = node.next
      node.next = newNode
      this.length++
      this.view2(this.head,1)
      return this
    }
  }

Así lo hice yo, ahora a ver como se hace

insert(value, pos){
    const newNode = new Node(value);
    let tail;
    let nodes = [this.head];
    if(pos >= 0 && pos <= this.length - 1){
        for(let i = 0; i <= pos; i++){
            if(nodes[nodes.length - 1].next){
                if(i == pos - 1){
                    tail = nodes[nodes.length - 1].next;
                    nodes[nodes.length - 1].next = newNode;
                }
                nodes.push(nodes[nodes.length - 1].next);
            }else{
                nodes[nodes.length - 1].next = tail;
                this.length++;
                return this.head;
            }
        }
    }else{
        if(pos <= this.length){
            this.prepend(newNode);
        }else{
            this.append(newNode);
        }
    }
}

Así implemente yo los metodos append y prepend:


class Node  {
    constructor(value){
        this.value = value;
        this.next = null
    }
}

class MySinglyLinkedList  {
    constructor(value) {
        this.head = {
            value: value,
            next: null
        }
        this.tail = this.head;
        this.length = 1;
    }

    append(value){
        let newNode = new Node(value)

        let lastNode = this.head;
        
        for(let i = 1; i  < this.length; i++){
            lastNode = lastNode.next;
        }

        lastNode.next = newNode;

        this.length++;
        this.tail = newNode;

        return this;
    }

    prepend(value) {
        let newNode = new Node(value);

        newNode.next = this.head

        this.head = newNode;

        this.length++;

        return this;
    }
}

Este fue el reto de la anterior clase así fue que lo hice

class Node {
  constructor(value) {
    this.value = value
    this.next = null
  }
};

class mySinglyLinkedList {
  constructor(value) {
    this.head = {
      value: value,
      next: null
    }
    this.tail = this.head;
    this.length = 1;
  }
  push(value) {
    this.tail.next = new Node(value);
    this.tail = this.tail.next
    this.length++
    return this.head;
  }
};


const myLinkedList = new mySinglyLinkedList(1);

myLinkedList.push(2);
myLinkedList.push(5);
myLinkedList.push(4);
myLinkedList.push(5); 
myLinkedList.push(3);
myLinkedList.push(8);

myLinkedList.length;

Mi solución para agregar un elemento en un índice cualquiera:

 insert( index, value ) {
        if( index < 0 ) return;
        if( index >= this.length-1 )return this.append(value);
        if (index === 0) return this.prepend(value);
            
        const newNode = new Node( value );
        let nodeAt = this.head;
        for ( let i = 1 ; i <= this.length ; i++) {
            if(i === index){
                newNode.next = nodeAt.next;
                nodeAt.next = newNode;
                this.length++
                return this;
            }else{
                nodeAt = nodeAt.next
            }
        }
        return this
    }

Git hub copilot lo hizo por mi, anyway era la lógica que tenia en mente desarrollar 😄

    constructor(value) {
        this.head = new Node(value);

        this.tail = this.head;
        this.length = 1;
    }
    append(value) {
        const newNode = new Node(value);
        this.tail.next = newNode;
        this.tail = newNode;
        this.length++;
    }


Método append (position es diferente a index, dado que comienza desde 1):

    insert (value, position) {
        const newNode = new Node(value);
        let prevNode;
        let node = this.head;
        let nextNode;

        for (let i = 1; i < position; i++) {
            if (i == position - 1) {
                prevNode = node;
                nextNode = node.next;
            }
            node = node.next;
        }

        prevNode.next = newNode;
        newNode.next = nextNode;

        this.lenght++;

        return this;
    }

Mi solución al reto 😄:

class node {
    constructor(value) {
        this.value = value;
        this.next = null;
    }
}

class singleLinkedList {
    constructor(value) {
        this.head = {
            value : value,
            next : null
        }

        this.tail = this.head;

        this.length = 1;
    }

    append(newValue) {
        this.tail.next = new node(newValue);
        this.tail = this.tail.next;
        this.length+=1;
    }

}

let myLinkedList = new singleLinkedList(10);

Aquí les comparto mi metodo insert

insert(value, numInsertNode) {
        const node = new Node(value);
        let nodeSelected = this.head;
        if(numInsertNode > this.length) {
            numInsertNode = this.length;
        }
        for(let i = 0; i < this.length; i++) {
            if(i === numInsertNode){
                node.next = nodeSelected;
            }
            nodeSelected = nodeSelected.next;
        }

        let insertNode = this.head;
        for(let i = 0; i <= numInsertNode; i++) {
            if(i === numInsertNode -1){
                insertNode.next = node;
                break;
            }
            insertNode = insertNode.next;
        }
        if(this.length === numInsertNode){
            this.tail = node;
        }

        this.length++;
        return this;
    }
class Node {
  constructor(value){
    this.value = value;
    this.next = null;
  }
}


class MySinglyLinKedList {
  //Se genera con un valor 
  constructor(value){
    this.head = {
      value: value,
      next: null,
    }
    this.tail = this.head;
    this.length = 1;
  }

  checknode(node){
    if (!node.next){
      return node;
    }
    return this.checknode(node.next);
  }

  //Problema es que solo actualiza ese primer next 
  //Tenemos que crear otro next
  append(value){
    //Recibir el valor del nodo
    let current = new Node(value);
    //Creamos que vaya al siguiente next creado
    const lastNode = this.checknode(this.head);
    lastNode.next = current
    //Cambiamos el valor next del head
    this.tail = current;
    this.length++;
    return this.head;
  }

}

let myLinkedList = new MySinglyLinKedList(1);
console.log(myLinkedList.append(2))
console.log(myLinkedList.append(3))

Mi método append()

append(value){
    const newNode = new Node(value);
        
    this.tail.next = newNode;
    this.tail = newNode;
    
    this.length++;
}

Convierte tu LinkedList a un array

toArray() {
    const arr = [];
    let n = this.head;
    do {
      arr.push(n.value);
      n = n.next;
    } while (n);
    return arr;
  }
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class LinkedL {
  constructor(value) {
    this.head = {
      value,
      next: null,
    };

    this.tail = this.head;
    this.len = 1;
  }

  append(val) {
    const n = new Node(val);
    this.tail.next = n;
    this.tail = n;
    this.len++;
  }
}

const l = new LinkedL(1);
for (let i = 0; i < 14; i++) {
  l.append(i);
}
console.log(l);

Les comparto el método toString para que puedan imprimir los valores de la SingleLinkedList de manera más visual:

toString() {
  let current = this.head
  let linkedList = `${[current.value]} -> `

  while(current.next) {
    current = current.next
    linkedList += `${[current.value]} -> `
  }

  linkedList += 'null'

  return linkedList
}

metodo append con explicacion

  append(value){
    this.length++
    // se crea un nodo, unico e irrepetible. solo referenciable.
    const node = new Node(value)
    
    /* la primera vez:
    this.tail.next apunta a this.head.next por lo que los dos apuntan hacia node
    entonces: 
      this.head == 
      this.tail == 
      {value: 1, next: node} ==
      {value: 1, next: {value: 2, next: null}}
    vv
    en la siguente linea this.tail ahora apunta unicamenxd7 te al node al que se asigno a head. 
    entonces:
      this.tail !== this.tail
      this.tail == node
      this.head == {value: 1, next: node}
      this.head == {value: 1, next: this.tail}
      
    por lo que tail termina apuntando a la ultima posicion de head, y en las siguientes veces que sea convocada la funcion los cambios de tail seran reflejados la ultima posicion de head
    */
    this.tail.next = node 
    this.tail = node
    // while(curr.next !== null) curr = curr.next
    // curr.next = node
  }
  append(value){
    this.length++
    let curr = this.head
    const node = new Node(value)
    while(curr.next !== null) curr = curr.next
    curr.next = node
  }

Creo que así no era JAJAJAJAJAJ.

//Asi es como yo hize el mecanismo para agregar un nuevo nodo, sin embargo creo que el del profesor va a estar mejor haha.
    append(value){
        const linkNode = new NodeLink(value);
        this.recorrer(this.head, linkNode); // Este metodo nos va a servir para recorrer el objeto en todas sus profundidades
    }
    recorrer(obj, node) { // Recibe dos parametros, el objeto que queremos que recorra y el nodo que queremos que agregue
        for (let properties in obj) { // properties representa cada uno de los index/keys que tiene el objeto
            if (this.isObject(obj[properties])) { // Verifica si el value de la key que esta recorriendo es un objeto por el metodo isObject() definida abajo
                this.recorrer(obj[properties], node); // Si alguno de los values del objeto es otro objeto se va a llamar a ella misma, usando recursividad
            } else if (obj[properties] === null ) { // Si no, entonces miremos si esos values tiene null, que es el value del next
                obj[properties] = node; // Si lo encuentra entonces vas a asignar a ese value el nodo que le pasamos como parametro
                this.tail = node; // Lo va a volver la cola de la linked list
                this.length++; // Vamos a aumentar el registro
                return this.head; // Y vamos a retornar this.head
            }
        }
    }
    isObject(obj) {
        return Object.prototype.toString.call(obj) === '[object Object]'; // Nos metemos en el prototype de toString() para añadirle un this que sea el objeto que queremos verificar si es un objeto, si ese string sale a dicha representacion, devuelve true
    }

Inicia explicación

Yo lo hice un poco diferente, dejo el metodo prepend y el codigo completo explicado como tambien el resultado

// Metodo para agregar un nodo al inicio.
// Este metodo recibira el valor que tendra el nodo.
preppend(value) {
    // Creamos nuestro nuevo nodo, este recibira el valor que contendra y el valor de next,
    // Que en este caso sera this.head, esto quiere decir que el valor que este en este momento en el head de nuestra linkedList
    // Sera el siguiente del nuevo nodo
    const newNode = new Node(value, this.head);

    //Validamos si existe un nodo en el head, es decir, si nuestra LinkedList No esta Vacia
    if (!this.head) {
      // Si no existe un valor en el head quiere decir que nuestra linkedList esta vacia
      // Entonces el nodo que estamos agregando es el primer nodo por lo cual sera el head y el tail a la vez
      this.tail = newNode;
    }

    // Si no se cumple la validacion anterior quiere decir que nuestra linkedList tiene elementos.
    // Entonces al head tenemos que apuntarlo al nuevo nodo
    this.head = newNode;
    // Por ultimo Incrementamos en 1 la longitud de la LinkedList
    this.length++
  }

código final

// creación del Nodo, que recibe como parametro las propiedades que tendra dicho nodo
class Node {
  // Como sabemos en una SinglyLinkedList los nodos solo tendran dos valores
  constructor(value,next) {
    this.value = value; //value, que sera el dato que contendra el nodo
    this.next = next; // next, que hará referencia al siguiente nodo
  }
}

// Creacion de la clase SinglyLinkedList que contendra toda la logica de nuestra LinkedList
class SinglyLinkedList {
  // Esta clase tendra como propiedades el head y el tail el cual estaran inicializados en null
  // esto quiere decir que empezaremos con una LinkedList Vacia y por ende su longitud sera 0
  constructor(){
    this.head = null;
    this.tail = null;
    this.length = 0;
  }

  // implementacion del metodo append, este agregara un nodo al final de la LinkedList
  // y recibira como parametro el valor que contendra el nodo que se insertara
  append(value) {
    const newNode = new Node(value, null);

    // hacemos una validacion si existe algun nodo al final de la LinkedList.
    if(this.tail) {
      // Si existe un nodo al final, entonces decimos que su next sera el nuevo nodo que creamos
      this.tail.next = newNode;
    } else {
      // Si no existe quiere decir que nuestra LinkedList esta vacia.
      // Esto quiere decir que el Nodo que esta agregando es el primero
      // Como es el primero entonces ese nodo sera el head y el tail a la vez.
      // por lo cual al head le asignamos el nuevo nodo
      this.head = newNode;
    }
    // Colocamos al nodo creado como el tail 
    this.tail = newNode;
    // Incrementamos en 1 la longitud de nuestra lista
    this.length ++;
  }
  
  // Metodo para agregar un nodo al inicio.
  // Este metodo recibira el valor que tendra el nodo.
  preppend(value) {
    const newNode = new Node(value, this.head);

    if (!this.head) {
      this.tail = newNode;
    }
    
    this.head = newNode;
    this.length++
  }
}

Solución

Algo así quedó:

class MySinglyLinkedList {
  constructor(value) {
    this.head = {
      value: value,
      next: null
    };
    this.tail = this.head;

    this.length = 1;
  }

  append(value) {
    let currentNode = this.head;
    let newNode = new Node(value);
    this.head = newNode;
    this.head.next = currentNode;
    if (currentNode.next == null) {
      this.tail = currentNode;
    }
    this.length++;
  }
}

I implemented the append method with a recursive method so I didn’t have to use the tail prop. The list and trees can be handled with recursion.

append(value){
    
    
      let newNode = this.searchTail(this.head, value);
      this.tail = newNode;
      this.length++;
  }

  searchTail(node, value){

    if(!node.next){
      const newNode = new Node(value);
      node.next = newNode;
      return newNode;
    }else{
      return this.searchTail(node.next, value)
    }
  }


Reto terminado

    insert(index,value){
        const newNode = new Node(value);
        let target = this.head;
        let slice = undefined;
        for (let i = 1; i < index; i++) {
            target = target.next;
        }
        slice = target.next;
        target.next = newNode;
        target.next.next = slice;
        return console.log(this.head);
    }
me voló la cabeza; intente hacerlo por mi cuenta y ya estaba pensando en bucles super complejos para recorrer los objetos, pero básicamente es jugar con la referencia del objeto. uff , valió la pena cada centavo

asi fue mi solución:

append(value){
        const newNode = new Node(value);
        this.recursiveMethod(this.head,newNode)
        this.length ++;
        return this.head;
    }
    recursiveMethod(obj, newNode){
        if(obj.next === null){
            return obj.next = newNode;
        }
        for(let prop in obj){
            if(prop === 'next')
            {
                this.recursiveMethod(obj[prop],newNode);
            }
        }
    }
class myNode {
  constructor(value) {
    this.data = value;
    this.next = null;
  }
}

class MySinglyLinkedList {
  constructor() {
    this.head = null;
    this.tail = this.head;
    this.length = 0;
  }

  append(value) {
    const newNode = new myNode(value);
    if (this.head === null) {
      this.head = newNode;
    } else {
      this.next = newNode;
    }
    this.tail = newNode;
    this.length++;

    return this;
  }
}

let mySinglyLinkedList = new MySinglyLinkedList();

antes de seguir con el curso aca dejo mis metodos para comparar despues

append(value) {
    this.tail.next = new Node(value)
    this.tail = this.tail.next
    this.length++

    return this.tail
  }

  prepend(value) {
    let newHead = new Node(value)
    newHead.next = this.head
    this.head = newHead
    this.length++
    
    return this.head
  }

re mal amigo 😂

    insert(value, position){

        for(let i=0; i<this.length; i++){
            if(Object.keys(this.head.next) < 1 ){
                if(this.head.value === position){
                    this.prepend(value)
                    this.length ++;

                }
            }
        }
        return this
    }

Orale! Vamos a intentarlo carnales

Aqui les dejo otra forma mas simplificada de hacer el prepend (Ecma)

    prepend(value) {
        let newNode = new node(value)
        this.head = {...newNode, next: this.head}
        this.length ++;
        return this;
    }

ejercicio del append resulto antes de ver el video

class Nodo {
  constructor(value) {
    this.value = value;
    this.next = null;
  }

  getNodo(){
      return{
          value:this.value,
          next: this.next,
      }
  }
}

class MySinglyLinkedList {
    
    constructor(value) {
        this.head = {
        value: value,
        next: null,
        };
        this.tail = this.head;

        this.length = 1;
    }

    append(value){
        this.tail = new Nodo(value).getNodo();
        this.length++;
        this.head.next = this.tail;
        return this.head;
    }
}

Estoy en el minuto 8:58 espero que esta solucion sea la correcta 😄

MY NOTES FROM NODES TO THE LIST 😄

class Node{

  constructor(value){

    this.value = value;
    this.next  = null;
  }
}

class MySinglyLinkedList{

  constructor(value){

    this.head = {
      value: value,
      next: null,


    }
    this.tail = this.head;

    this.length = 1;
  }
  append(value){
    //generamos una constante en la cual vamos a generar un nuevo
      //Nodo que se va a colocar en la cola de nuestra lista
        //Hacemos una instancia de la clase que crea nuestros nodos
    const newNode = new Node(value);
    //Le asignamos a la cola el nuevo nodo pero para la fila el ultimo nodo
      //Que habia en la fila sigue siendo la fila
    this.tail.next = newNode;

    //Luego le indicamos a la fila que el ultimo nodo es el que creamos
    this.tail = newNode;

    //Incrementamos la logintud de nuestra lista
    this.length++;

    return this;



  }

  prepend(){

    const newNode = new Node(value);

    newNode.next = this.head;

    this.head = newNode;

    this.length++;

    return this;





  }

}

let myLinkedList = new MySinglyLinkedList(1);

mi humilde aporte
![](

insert(nodeNumber, value){
    // 1 2 3 4 5
    if(nodeNumber > this.length){
      return undefined;
    }else if(nodeNumber === 0){
      this.prepend(value);
      return this;
    }else if(nodeNumber === this.length -1){
      this.append(value);
      return this;
    }
    
    const newNode = new Node(value);
    let pointer = this.head;
    for(let i = 0; i < (nodeNumber - 1); i++){
      pointer = pointer.next;
    }
    newNode.next = pointer.next;
    pointer.next = newNode;
    this.length++;
    return this;
  }

Prácticamente el ejemplo que se genera en esta clase juega con las referencias por eso al momento de modificar el head tail se ve afectado

Mi solución:

class Node {
    constructor (value) {
        this.value = value;
        this.next = null;
    }
}

class MySinglyLinkedList {
    constructor(value) {
        this.head = new Node(value);
        this.tail = this.head;
        this.length = 1;
    }
    append(value) {
        const newNode = new Node(value);
        this.tail.next = newNode;
        this.tail = newNode;
        this.length++;
    }
}

Método insert

insert(value, index){
        if(index<this.length){
            let currentNode = this.head;
            let before;
            for(let i=0;i<this.length;i++){
                if(i===index-1){
                    let node = new Node(value);
                    node.next = currentNode;
                    before.next = node;
                    this.length++;
                    return this;
                }
                before = currentNode;
                currentNode = currentNode.next;
            }
        }else{
            return "overflow"
        }
    }

Mi insert para el reto 😊

insert(value, position) {
        if(position <= this.length) {
            if (position === 0) this.prepend(value)
            else if (position === (this.length)) this.append(value)
            else {
                let aux = this.head
                let newNodo = new Nodo(value)
                for(let i = 1; i < position; i++){
                    aux = aux.next
                }
                newNodo.next = aux.next
                aux.next= newNodo 
                this.length++
            }
        }
    }```

Ahí va la implementación del método insert:

    insert ( value, position ){

        if( position === 0)
            this.prepend( value )
        else if( position === this.length )
            this.append( value )
        else {

            const insertedNode = new Node( value )
            
            let previousNode = this.head
            
            for( let i=1; i < position; i++){
                previousNode = previousNode.next
            }
            
            let nextNode = previousNode.next
            
            insertedNode.next = nextNode
            previousNode.next = insertedNode
            
        }
        
        this.length += 1
        return this
    }

Solución al reto

insert(value, index) {
    if (index === 0) {
      this.prepend(value);
      return;
    }
    if (index === this.length) {
      this.append(value);
      return;
    }
    
    const newNode = new Node(value);
    let auxNode = this.head;
    for (let i = 0; i < index-1; i++) {
      auxNode = auxNode.next;
    }
    newNode.next = auxNode.next;
    auxNode.next = newNode;
    this.length++;
    return this;
  }