No tienes acceso a esta clase

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

Implementando el método Get

12/29
Recursos

Aportes 199

Preguntas 16

Ordenar por:

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

De forma grafica como se llega a cada elemento dentro de los buckets, y del currentBucket, a que arreglo de arreglos de clave, valor:

Saludos 😃

👩‍💻👨‍💻 Código de la clase y solución al reto de Remove y getAllKeys

class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }
  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    return this.data;
  }

  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          return currentBucket[i][1];
        }
      }
    }
    return undefined;
  }

  getAllKeys() {
    const keys = [];
    for (let i = 0; i < this.data.length; i++) {
      if (this.data[i]) {
        for (let j = 0; j < this.data[i].length; j++) {
          keys.push(this.data[i][j][0]);
        }
      }
    }
    return keys;
  }

  remove(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          const deletedValue = this.data[address][i];
          this.data[address].splice(i, 1);
          return deletedValue;
        }
      }
    }
    return undefined;
  }
}

Creo que ha llegado el momento que rehagan TODOS los cursos de Javascript y que los haga Diego, este es su curso más complejo sobre Javascript que ha enseñado y sin embargo se entiende todo, hasta había entendido la lógica del matriz de arrays antes de que lo explique con el [ [], [], …] y eso que yo no suelo entender a la primera…

 getKeys() {
    return this.data.reduce((instance, value) => {
      const keys = value.map(([key]) => key);
      return instance.concat(keys)
    }, []);
  }

me perdi 😦 pero seguire!

Dejo el código del delete (Es prácticamente lo mismo que el get, pero en esta ocasión lo elimina con delete), le puse remove para que el linter de JS no me diera problemas ^^

remove(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    const element = currentBucket[i][1];
                    delete currentBucket[i][1];
                    return element;
                }
            }
        }
        return undefined;
    }

mm no veo aun el potencial de este curso, veo muchas cosas repetidas de otros

My solucion para el metodo getKeys y delete

/* eslint-disable no-restricted-syntax */
/* eslint-disable no-plusplus */
class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }

  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }

  delete(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          const value = currentBucket[i];
          currentBucket.splice(i, 1);
          return value;
        }
      }
    }
    return undefined;
  }

  keys() {
    const keys = [];
    this.data.forEach((bucket) => {
      bucket.forEach((keyPairValues) => {
        keys.push(keyPairValues[0]);
      });
    });
    return keys;
  }

  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    return this.data;
  }

  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) { return currentBucket[i][1]; }
      }
    }
    return undefined;
  }
}

const myHashTable = new HashTable(50);
myHashTable.set('franz', 1997);
myHashTable.set('laura', 1998);
myHashTable.set('mama', 1966);
myHashTable.set('elena', 2000);
myHashTable.get('franz');
myHashTable.keys();
myHashTable.delete('mama');
myHashTable.keys();

Hay un detalle con la función de set, es que si haces dos veces un set de la misma llave entonces sólo lo vas a añadir al arreglo y cuando trates de hacer un get te devuelve el primer valor y nunca los que se añadieron de manera posterior, estuve viendo que en la implementación de Hash Table que tiene Java lo que hacen es sobreescribir el valor de la llave con el nuevo, más info al respecto acá. Para emular este comportamiento cambié un poco el método, y quedó así:

      set(key, value) {
        const address = this.hashMethod(key);
        if (!this.data[address]) {
          this.data[address] = [];
        }
        if (this.data[address].find((element) => element[0] === key)) {
          for (let i = 0; i < this.data[address].length; i += 1) {
            if (this.data[address][i][0] === key) {
              this.data[address][i][1] = value;
            }
          }
        } else {
          this.data[address].push([key, value]);
        }
        return this.data;
      }

También les comparto mis notas sobre éste módulo acá 😁.

// RECIBE LA LLAVE QUE BUSCAMOS CON SU VALOR
    get(key){

        // LLAMAMOS LA FUNCION QUE NOS DEVUELVE UN HASH
        const address = this.hashMethod(key)

        // EL ADDRESS EN DONDE SE ENCUENTRA LA INFORMACIÓN
        const currentBucket = this.data[address]

        // SI ES TRUSTY 
        if( currentBucket )
        {
            // DESDE 0 HASTA EL LARGO DE EL CURRENT BUCKET
            for( let i = 0 ; i < currentBucket.length; i++ ) {

                // SI LA POSICION 0 DE EL ARREGLO ES IGUAL EL 
                // KEY QUE NOS PASARON
                if( currentBucket[i][0] === key) 
                {
                    // DEVOLVEMOS LA POSICION 1 QUE APUNTA A SU VALOR
                    return currentBucket[i][1]
                }
            }

        }
        // DEVOLVEMOS UNDEFINED
        return undefined

 }
<h3>Resuelto el reto 😁</h3>

Añadí un método findPair a la clase y lo que hace es abstraer la lógica de búqueda del método get, para poder usarla a la vez en el método de delete, y no repetir código.
Y para aplicar la lógica de si buscar un value o eliminar, recibe un callback como segundo parámetro que inyecta el valor del currentBucket y del index actual

class HashTable {
	constructor(size) {
		this.data = new Array(size);
	}

	hashMethod(key) {
		let hash = 0;

		for (let i = 0; i < key.length; i++) {
			hash = (hash + key.charCodeAt(i) * i) % this.data.length;
		}
		return hash;
	}

	set(key, value) {
		const address = this.hashMethod(key);

		if (!this.data[address]) {
			this.data[address] = [];
		}
		this.data[address].push([key, value]);

		return this.data;
	}

	get(key) {
		return this.findPair(key, (currentBucket, index) => currentBucket[index][1]);
	}

	getAllKeys() {
		const allKeys = [];

		this.data.forEach((bucket) => {
			for (let i = 0; i < bucket.length; i++) {
				allKeys.push(bucket[i][0]);
			}
		})

		return allKeys;
	}

	delete(key) {
		return this.findPair(key, (currentBucket, index) => {
			const pair = currentBucket[index];
			currentBucket.splice(index, 1);
			return pair;
		})
	}

	findPair(key, callback) {
		const address = this.hashMethod(key);
		const currentBucket = this.data[address];

		if (currentBucket) {
			for (let i = 0; i < currentBucket.length; i++) {
				if (currentBucket[i][0] === key) {
					return callback(currentBucket, i);
				}
			}
		}

		return undefined;
	}
}

const myHashTable = new HashTable(50);

myHashTable.set('Diego', 1990);

myHashTable.set("Mariana", 1998);

myHashTable.set("Alejandra", 2000);

Esta es mi propuesta al método para obtener todas las keys de una hastable.

  getKeys() {
    let keys = [];
    for (let i = 0; i < this.data.length; i++) {
      if (this.data[i]) {
        for (let j = 0; j < this.data[i].length; j++) {
          keys.push(this.data[i][j][0]);
        }
      }
    }
    return keys;
  }

Agradeceria su feedback

Les comparto la forma en que lo hice jaja, y suerte 😄

class HashTable {
    constructor(size){
        this.data = new Array(size);
    }

    hashMethod(key){
        let hash = 0;
        for (let i = 0; i < key; i++){
            hash = (hash + key.chartCodeAt(i) * i ) % this.data.length;
        }
        return hash;
    }

    set(key, value){
        const address = this.hashMethod(key);
        if(!this.data[address]){
            this.data[address] = [];
        }

        this.data[address].push([key, value]);

        return this.data;
    }

    get(key){
        const currentBucket = this.getCurrentBucket(key);
        if(currentBucket){
            for(let i = 0; i < currentBucket.length; i++){
                if(currentBucket[i][0] === key){
                    return currentBucket[i][1];
                }
            }
        }
        return undefined;
    }

    delete(key){
        const currentBucket = this.getCurrentBucket(key);
        let item;
        if(currentBucket){
            for(let i = 0; i < currentBucket.length; i++){
                if(currentBucket[i][0] === key){
                    item = currentBucket[i];
                    this.data[address] = currentBucket.filter(j => j[0] !== key);
                }
            }
        }
        return item || undefined;

    }

    getKeys(){
        const address = this.hashMethod();
        const currentBucket = this.data[address];
        return currentBucket.map(i => i[0]);
    }

    getValues(){
        const address = this.hashMethod();
        const currentBucket = this.data[address];
        return currentBucket.map(i => i[1]);
    }

    getAll(){
        return this.getCurrentBucket().map(i => ({ key:i[0], value: i[1] }));
    }

    find(value){
        const result = this.getCurrentBucket().filter(i => i[1] === value).map(i => ({
            key:i[0], value: i[1]
        }))
        return result.length > 1 ? result : result[0] || undefined;
    }

    getCurrentBucket(key){
        let address = key ? 
                        this.hashMethod(key) 
                        : this.hashMethod();
        return this.data[address];
    }
}

const myHashTable = new HashTable(50);

Les comparto mi solución al reto:

delete(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    for (let i = 0; i < currentBucket.length; i++) {
      if (currentBucket[i][0] === key) {
        const deleted = currentBucket[i][1];
        this.data[address].splice(i, 1);
        return deleted;
      }
    }
    return undefined;
}

getKeys() {
    let keys = [];
    for (let address of this.data) {
      if (!address) {
        continue;
      }
      for (let [key, value] of address) {
        keys.push(key);
      }
    }
    return keys;
}
Dejo por aquí mi implementación de los métodos "delete" y "viewKeys" ✨. ![](https://i.imgur.com/Pbh88Mh.png)
Compartiré por aquí mi implementación del método get usando el método .find de los arrays ✨~ ![](https://i.imgur.com/juuC3ya.png)
Aunque se entiende que en el metodo get, se hace una iteración por posibles colisiones, lo correcto es hacer la hash funcion lo más óptima posible, para evitar colisiones. Hay que entender que lo que intenta solucionar la hash table, es que a la hora de tu buscar un elemento en la matriz, no tengas que integrar todos los elementos para buscar un solo valor, la idea es que gracias a la hash funcion ya tu recuperes ese elemento directamente, sin iterar. Lo que se hace en el video es con fines didácticos y está bien, pero si hacen un for para buscar un valor en una hash table en un ámbito real, está mal.

Por si alguien quiere copiarlo 🫡 dejo el mismo código .get(key) del profesor pero con los console.log( ) 👾que he creado para ver el proceso interno que sigue:

  get(key) {
    const address = this.hashMethod(key);
    console.log('El hash/address que debería tener', key ,'es:', address)
    const currentBucket = this.data[address];
    if (currentBucket) {
      console.log('Efectivamente, existe this.data[', address, ']')
      for (let i = 0; i < currentBucket.length; i++) {
        console.log('Iteración', i, 'en this.data[', address, ']')
        if (currentBucket[i][0] === key) {
          console.log('Efectivamente, hay un array cuya posición [0] es', key)
          console.log('Así que devuelvo su valor (que se encuentra en la posición [1]):', currentBucket[i][1])
          return currentBucket[i][1];
        }
      }
    }
    console.log('Este this.data[', address, '] no existe en la Hash Table')
    return undefined;
  }
Acá dejo mi solución para allKeys ```js getAllKeys(){ let allKeys = []; let i = 0; console.log("afuera " + this.data) while(i < this.data.length){ if(this.data[i]){ console.log("this data" + this.data[i]) allKeys.push(this.data[i][0][0]); } i++; } console.log(allKeys); } ```
Método Delete ```js delete(key) { const address = this.hashMethod(key); const currentBucket = this.data[address]; if (currentBucket) { for (let i = 0; i < currentBucket.length; i++) { if (currentBucket[i][0] === key) { const data = currentBucket[i]; currentBucket.splice(i, 1); if (currentBucket.length === 0) { delete this.data[address]; } return data; } } } return undefined; } ```  delete(key) {    const address = this.hashMethod(key);    const currentBucket = this.data\[address];    if (currentBucket) {      for (let i = 0; i < currentBucket.length; i++) {        if (currentBucket\[i]\[0] === key) {          const data = currentBucket\[i];          currentBucket.splice(i, 1);          if (currentBucket.length === 0) {            delete this.data\[address];          }          return data;        }      }    }    return undefined;  } Método getAllKeys ```js getAllKeys() { const keys = []; this.data.forEach( bucket => bucket.forEach(info => keys.push(info[0])) ); return keys; } ```  getAllKeys() {    const keys = \[];    this.data.forEach(      bucket => bucket.forEach(info => keys.push(info\[0]))    );    return keys;  }

reto N1:

reto N2:

Mi solución ```js class HashTable { constructor(size) { this.data = new Array(size); } hashMethod(key) { let hash = 0; for (let i = 0; i < key.length; i++) { hash = (hash + key.charCodeAt(i) * i) % this.data.length; } return hash; } set(key, value) { const address = this.hashMethod(key); if (!this.data[address]) { this.data[address] = []; } this.data[address].push([key, value]); return this.data; } get(key) { const address = this.hashMethod(key); const currentBucket = this.data[address]; if (currentBucket) { for (let i = 0; i < currentBucket.length; i++) { if (currentBucket[i][0] === key) { return currentBucket[i][1]; } } } return undefined; } getHashes() { const hashes = []; this.data.forEach(bucket => { bucket.forEach(element => { hashes.push(element[0]); }); }); return hashes; } delete(key) { const address = this.hashMethod(key); const currentBucket = this.data[address]; if (currentBucket) { for (let i = 0; i < currentBucket.length; i++) { if (currentBucket[i][0] === key) { return currentBucket.splice(i, 1); } } } return undefined; } } const myHashTable = new HashTable(50); myHashTable.set('Esteban', 1992); myHashTable.set('Rosa', 1982); myHashTable.set('Daniel', 2014); myHashTable.set('Juan', 2000); myHashTable.set('Esteban', 2011); myHashTable.set('Rocio', 1992); myHashTable.set('Daniela', 1995); myHashTable.set('Alberto', 1993); myHashTable.set('Damian', 1986); myHashTable.set('Gustavo', 1989); myHashTable.set('Barbara', 1990); console.log('Hashes antes de eliminar elementos', myHashTable.getHashes()); console.log('Eliminado: ',myHashTable.delete('Barbara')); console.log('Eliminado: ',myHashTable.delete('Damian')); console.log('Eliminado: ',myHashTable.delete('Esteban')); console.log('Hashes despues de eliminar elementos: ',myHashTable.getHashes()); ```

Les comparto un codigo que te ayuda a encontrar keys que provocan colisiones, para así probar en caso se produzcan mas de 2.

PD. El codigo solo muestra un key por ejecución

function hashMethod(key, length) {
  let hash = 0;
  for (let i = 0; i < key.length; i++) {
    hash = (hash + key.charCodeAt(i) * i) % length;
  }
  return hash;
}

const targetHash = hashMethod('Diego', 50); // Calcula el hash para 'Diego'

// Genera claves aleatorias y verifica si su hash coincide con el hash objetivo
while (true) {
  const key = Math.random().toString(36).substring(2, 7); // Genera una clave aleatoria
  if (hashMethod(key, 50) === targetHash) {
    console.log('Colisión encontrada con la clave:', key);
    break;
  }
}
class EHashTable{
  constructor($_size) {
    this.length = 0,
    this.data = Array($_size)
  }

  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }

  set($_key,$_value){
    // Hashing key
    const address = this.hashMethod($_key)
    let bucket = this.data[address];
    // Handle collisions
    bucket = bucket ?? []
    // Check if key exists
    if(!bucket.find(ele => ele[0] === $_key)){
        // push new item 
        bucket.push([$_key,$_value]);
        // increment length
        this.length++;
    }else {
      throw new Error('Key already exists');
    }
    // Set bucket back
    this.data[address] = bucket;

    return this.data;
  }

  get($_key) {
    // Use find method to locate entry
    const entry = this.findEntry($_key)
    // Returns the value if the key is found
    return entry ? entry[1] : undefined; 
  }

  findBucket($_key){
    const address = this.hashMethod($_key);
    return this.data[address];
  }

  findEntry($_key){
    const bucket = this.findBucket($_key);
    if(!bucket) return undefined;
    // Find entry with matching key
    return bucket.find(entry => entry[0] === $_key)
  }

  remove($_key){
    const entry = this.findEntry($_key)
    const value = entry ? entry[1] : undefined;

    if(entry){
      // Locate bucket
      const bucket = this.findBucket($_key);
      // Remove entry from bucket
      bucket.splice(bucket.indexOf(entry), 1);
      // Removes the bucket if it's empty 
      if(bucket.length === 0){
        delete this.data[this.data.indexOf(bucket)];
      }
      // Decrement data length
      this.length--;
    }
    return value;
  }

  getAllKeys(){
    let keys = []
    Object.values(this.data).forEach(bucket => {
      keys = keys.concat( bucket.map(entry => entry[0]));
    })
    return keys;

  }
  
}

export default EHashTable;

realmente me toco hacer el codigo para entender y gracias lo entendi melo sin tantas vueltas

 delete(key){
  const address = this.hashMethod(key)
   const currentBucket  = this.data[address];
  if(currentBucket ){
    for(let i = 0;i < currentBucket.length;i++){
      if(currentBucket[i][0] == key){
        delete currentBucket[i][0]
      }
    }
  }
  return currentBucket
 }

Mi solucion al reto.
getAllKeys.

getAllKeys(){
        const keys = [];
        for (let i = 0; i < this.currentBucket.length; i++){
            if(this.currentBucket[i]){
                for(let j = 0; j < this.currentBucket[i].length; j++){
                    keys.push(this.currentBucket[i][j][0]);
                }
            }
        }
        return keys;
    }

Metodo delete.

delete(key){
        const address = this.hashMethod(key);
        if(!this.currentBucket[address]){
            return null;
        }
        for (let i = 0; i < this.currentBucket[address].length; i++){
            if (this.currentBucket[address][i].key === key){
                return this.currentBucket[address].splice(i,1);
            }
        }
        return null;
    }
<delete(key){
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          const item = currentBucket[i];
          console.log(item);
          for (let j = i; j < currentBucket.length; j++){
            currentBucket[j] = currentBucket[j+1];
          }
          if (currentBucket.length>1){
            delete currentBucket[currentBucket.length - 1];
            currentBucket.length--;
          } else{
            delete this.data[address];
          }
          return item;      
        }
      }
    } else{
        console.log(currentBucket);
        return currentBucket;
    }
  }

  getAllKeys(){
    const allKeys = [];
    for (let i = 0; i < this.data.length; i++){
      if (this.data[i]) {
        const currentBucket = this.data[i];
        for (let j = 0; j < currentBucket.length;j++)
          allKeys.push(currentBucket[j][0]);
      }
    }
    return allKeys;
  }> 
// Creamos una clase HashTable
class HashTable {
    // El constructor recibe un parámetro 'size'
    constructor(size) {
        // Crea una nueva matriz de tamaño 'size' y la almacena en el atributo 'data'
        this.data = new Array(size);
    }
    
    // El método '_hash' recibe una clave 'key' como parámetro
    _hash(key) {
        // Inicializa una variable 'hash' en cero
        let hash = 0;
        // Recorre la clave 'key' letra por letra
        for (let i = 0; i < key.length; i++) {
            // Calcula el valor hash multiplicando el código ASCII de la letra por su posición en la clave
            hash = (hash + key.charCodeAt(i) * i) % this.data.length;
        }
        // Retorna el valor hash
        return hash;
    }

    // El método 'set' recibe una clave 'key' y un valor 'value' como parámetros
    set(key, value) {
        // Calcula la dirección en la matriz donde se almacenará el par clave-valor utilizando el método '_hash'
        const address = this._hash(key);
        // Si la dirección aún no tiene elementos, crea un nuevo array
        if (!this.data[address]) {
            this.data[address] = [];
        }
        // Agrega el par clave-valor al array de la dirección correspondiente
        this.data[address].push([key, value]);
        // Retorna la matriz completa
        return this.data;
    }

    // El método 'get' recibe una clave 'key' como parámetro
    get(key) {
        // Calcula la dirección en la matriz donde debería estar la clave buscada
        const address = this._hash(key);
        // Obtiene el array correspondiente a esa dirección
        const currentBucket = this.data[address];
        // Si el array existe, busca la clave y devuelve su valor
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    return currentBucket[i][1];
                }
            }
        }
        // Si no encuentra la clave, retorna 'undefined'
        return undefined;
    }

    // El método 'delete' recibe una clave 'key' como parámetro
    delete(key) {
        // Calcula la dirección en la matriz donde debería estar la clave a borrar
        const address = this._hash(key);
        // Obtiene el array correspondiente a esa dirección
        const currentBucket = this.data[address];
        // Si el array existe, busca la clave y la borra del array
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    const deleted = currentBucket[i];
                    currentBucket.splice(i, 1);
                    // Retorna el par clave-valor borrado
                    return deleted;
                }
            }
        }
        // Si no encuentra la clave, retorna 'undefined'
        return undefined;
    }

    // El método 'getAllKeys' no recibe parámetros
    getAllKeys() {
        // Crea un array vacío para almacenar todas las claves
        const keysArray = [];
        // Recorre toda la matriz
        for (let i = 0; i < this.data.length; i++) {
            // Si la dirección de la matriz tiene elementos, recorre su array y agrega las claves al array 'keysArray'
            if (this.data[i]) {
                // Recorre cada elemento del array de la dirección correspondiente
                for (let j = 0; j < this.data[i].length; j++) {
                    // Agrega la clave del elemento actual al array de claves
                    keysArray.push(this.data[i][j][0]);
                }
            }
        }
        // Retorna el array de claves completo
        return keysArray;
    }
}

En resumen, el código define una clase HashTable que implementa una tabla hash para almacenar pares clave-valor. La clase incluye métodos para agregar, obtener y eliminar pares clave-valor, así como un método para obtener todas las claves almacenadas en la tabla hash. Se crea una instancia de la clase y se agregan varios pares clave-valor a la tabla hash. Al final, se imprime la tabla hash completa en la consola.

  remove(key){
    const address = this.hashMethod(key);
    let found = false;
    for(let i = 0; i < this.data[address].length; i++){
      if(found){
        this.data[address][i - 1] = this.data[address][i];
      }
      if(this.data[address][i][0] === key){
        delete this.data[address][i];
        found = true;
      }
    }
    if(found){
      this.data[address].pop();
      return true;
    }else{
      return false;
    }
  }
  keys(){
    return this.data.flat().map(value => value[0]);
  }

Método para borrar elementos según el key (algo importante es que si ingresas varios valores con el mismo key, al llamar este método, te borra sólo el primero que encuentres):

delete(key){
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        let currentIndex, bucketToDelete;
        if(currentBucket){
            for(let i = 0; i < currentBucket.length; i++){
                if(currentBucket[i][0] === key){
                    currentIndex = i;
                    bucketToDelete = currentBucket[i]
                    break;
                }
            }
           
            (currentIndex == 0) ? delete currentBucket[0] : false;
            for(let i = currentIndex; i < currentBucket.length; i++){
                currentBucket[i] = currentBucket[i+1];       
            }
           currentBucket.length--;
           return bucketToDelete;
        }
        return undefined;
    }

Método para traer todos los key:

getAllKeys(){
        const arrayKeys = [];
        const buckets =  [];
        for(let i = 0; i < this.data.length; i++){
            if(this.data[i] != undefined){
                buckets.push(this.data[i]);
            }
        }
        for(let i = 0; i < buckets.length; i++){
            for(let j = 0; j < buckets[i].length; j++){
                arrayKeys.push(buckets[i][j][0])
            }    
        }
        return arrayKeys;
    }

el code

class HashTable {
  constructor (size) {
    this.data = new Array(size);
  }
  hashMethod(key) {
    let hash = 0;
    for (let i =0; i<key.length; i++) {
      hash = (hash + key.charCodeAt(i)*i) % this.data.length;
    }
    return hash;
  }

  set(key, value) {
    const address = this.hashMethod(key);
    if(!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    return this.data;
  }

  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address]; // it will return an array when Colisión de hash happends
    console.log(currentBucket);
    if(currentBucket) {
      for(let i =0; i< currentBucket.length; i++) {
        if(currentBucket[i][0] === key) {
          return currentBucket[i][1];
        }
      }
    }

    return undefined;
  }
}

const myHashTable = new HashTable(50);

// BORRADO
delete(key) {
const address = this.hashMethod(key);
const currentBucket = this.data[address];
if (currentBucket) {
let borrado;
for (let i = 0; i < currentBucket.length; i++) {
if (currentBucket[i][0] === key) {
borrado = currentBucket[i][0];
currentBucket[i] = [];
return borrado;
}
}
}
return undefined;
}

// LISTADO TODAS LAS KEYS
listKeys() {
let existKeys = [];
for (let i = 0; i < this.data.length; i++) {
if (this.data[i]) {
let bucketData = this.data[i];
for (let i = 0; i < bucketData.length; i++) {
existKeys.push(bucketData[i][0]);
}
}
}
return existKeys;
}
}

Método delete:

    delete(key) {
      const address = this.hashMethod(key);
      const currentBucket = this.data[address];

      const index = this.data.indexOf(currentBucket);

      for(let i = index; i < this.data.length - 1; i++) {
        if(this.data[i+1]) {
          this.data[i] = this.data[i+1];
        }
      }
      delete this.data[address];
      delete this.data[this.data.length - 1];
      this.data.length--;
      return currentBucket;
    }

Para obtener todas las keys que existen en la hashtable:

    getAllKeys() {
      const allKeys = [];
      for(let i=0; i < this.data.length; i++) {
        if(this.data[i]) {
          allKeys.push(this.data[i][0][0]);
        }
      }
      return allKeys;
    }

Un pequeño aporte: se entiende que el profe escribió el método get de esa forma por motivos pedagógicos, para que nosotros le entendamos con facilidad, pero hemos escrito un código horrorosamente anidado.

  • Podemos pasar de esto:

  • A esto:

Incluso puede refactorizarse de una forma mucho más sencilla que la que yo propongo, te invito a responder este comentario con tu refactorización de nuestro método get.

Podríamos añadir un comentario a cada línea, indicando brevemente qué hace cada línea o un comentario al inicio del método describiendo su funcionalidad.
Es buena práctica siempre estar pensando en cómo refactorizar a pequeña escala tu código, o sea cómo hacerlo más legible y entre esas buenas prácticas, evitar la anidación es una de ellas.

Les comparto my función para obtener todas las keys. Luego de tantos intentos y repasar el código la reduje a una sola línea sin que perdiera su legibilidad, creo jjj

Reto completado, métodos delete y allKeys (funcionan en caso de colisiones):

.

.

class HashTable {
	constructor(size) {
		this.bucket = new Array(size);
	}

	//Metodo Hash (para obtenerlo)
	hashMethod(key) {
		let hash = 0;
		for (let i = 0; i < key.length; i++) {
			hash = (hash + key.charCodeAt(i) * i) % this.bucket.length;
		}
		return hash;
	}

	//Metodo insert
	insert(key, value) {
		const address = this.hashMethod(key);
		if (!this.bucket[address]) {
			this.bucket[address] = [];
		}
		this.bucket[address].push([key, value]);
		return this.bucket;
	}

	//Metodo insert
	get(key) {
		const address = this.hashMethod(key);
		const currentBucket = this.bucket[address];
		if (currentBucket) {
			if (currentBucket.length > 1) {
				// Inicio de Logica para colisiones:
				for (let i = 0; i < currentBucket.length; i++) {
					if (currentBucket[i][0] == key) {
						return currentBucket[i][1];
					}
				}
			} else if (currentBucket[0][0] == key) {
				return currentBucket[0][1];
			}
		}
	}

	//Metodo delete
	delete(key) {
		const address = this.hashMethod(key);
		const currentBucket = this.bucket[address];
		if (currentBucket) {
			if (currentBucket.length > 1) {
				// Inicio de Logica para colisiones:
				for (let i = 0; i < currentBucket.length; i++) {
					if (currentBucket[i][0] == key) {
						delete currentBucket[i];
					}
				}
			} else if (currentBucket[0][0] == key) {
				delete currentBucket[0];
			}
		}
	}

	//Metodo allKeys
	allKeys() {
		let allkeys = [];
		for (let i = 0; i < this.bucket.length; i++) {
			let actualBucket = this.bucket[i];
			if (actualBucket) {
				if (actualBucket.length > 1) {
					// Inicio de Logica para colisiones:
					for (let j = 0; j < this.bucket[i].length; j++) {
						allkeys.push(actualBucket[j][0]);
					}
				} else {
					allkeys.push(actualBucket[0][0]);
				}
			}
		}
		return allkeys;
	}
}
const test = new HashTable(100);
test.insert("Fabio", 1990);
test.insert("Yulieth", 1996);
test.insert("Alejandro", 2023);
test.insert("Laurita", 1995);
test.insert("Giova", 2001);
test.insert("Fabio Fernando", 1966);
test.allKeys();

Eliminar un key

delete (key){
    const address = this.hashMethod(key)
    const currentBucket = this.data[address]
    const elementToDelete = [] 
    if (currentBucket){
        const newCurrentBucket = []
        for (let i in currentBucket){
            if (currentBucket[i][0] !== key){
                newCurrentBucket.push(currentBucket[i])
            } else {
                elementToDelete.push(currentBucket[i]) 
            }
        }
        this.data[address] = [ ...newCurrentBucket ]
        return elementToDelete
    } 
    return `${key} does not exist`     
}

Listar todos los keys

getAllKeys (){
    const keys = []
    for (let i in this.data){
        if (this.data[i]){
            for (let j in this.data[i]){
                keys.push(this.data[i][j])
            }
        }
    }
    return keys
}

Código completo

class HashTable{
    constructor(size){
        this.data = new Array(size);
    }
    hashMethod(key){
        let hash = 0;
        for(let i = 0; i < key.length;i++){
            hash = (hash + key.charCodeAt(i)*i) % this.data.length;
        }
        return hash;
    }

    set(key, value) {
        const address = this.hashMethod(key)
        if (!this.data[address]){
            this.data[address] = []
        }
        this.data[address].push([key,value])
        return this.data[address]
    }
    
    get(key){
        const address = this.hashMethod(key)
        const currentBucket =  this.data[address]
        if (currentBucket){
            for (let index in currentBucket){
                if (currentBucket[index][0] === key) {
                    return currentBucket[index][1]
                }
            }
        }
        return undefined
    }

    getAllKeys (){
        const keys = []
        for (let i in this.data){
            if (this.data[i]){
                for (let j in this.data[i]){
                    keys.push(this.data[i][j])
                }
            }
        }
        return keys
    }

    delete (key){
        const address = this.hashMethod(key)
        const currentBucket = this.data[address]
        const elementToDelete = [] 
        if (currentBucket){
            const newCurrentBucket = []
            for (let i in currentBucket){
                if (currentBucket[i][0] !== key){
                    newCurrentBucket.push(currentBucket[i])
                } else {
                    elementToDelete.push(currentBucket[i]) 
                }
            }
            this.data[address] = [ ...newCurrentBucket ]
            return elementToDelete
        } 
        return `${key} does not exist`     
    }
}
// Esta es mi solucion. Complejidad N! Xd

class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  hashMetodo(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }
  set(key, value) {
    const address = this.hashMetodo(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);

    return this.data;
  }
  get(key) {
    const address = this.hashMetodo(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        console.log(currentBucket[i]);
        if (currentBucket[i][0] === key) {
          return currentBucket[i][1];
        }
      }
    }
    return null;
  }

  delete(key) {
    const address = this.hashMetodo(key); //! la pocicion harcodeada por la funcion de hash
    // console.log(this.data[address], address)
    const currentBucket = this.data[address];

    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        // console.log(currentBucket[i]);
        if (currentBucket[i][0] === key) {
          const elementeEliminado = currentBucket[i];
          delete currentBucket[i];
          return elementeEliminado;
        }
      }
    }
    return null;
  }

  getAllKey() {
    let currentKey = this.data;
    let keysEncontradas = [];
    if (currentKey.length > 0) {
      for (let i = 0; i < currentKey.length; i++) {
        if (currentKey[i] === undefined) {
          continue;
        }
        let encontradas = currentKey[i][0][0];
        keysEncontradas.push(encontradas);
      }
    }
    return keysEncontradas;
  }
}

hola sugerencias serian utiles

class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash % this.data.length;
  }
  /**El método set() llamará al método hash()
   *  para obtener el valor del índice. */
  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    return this.data;
  }
  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          return currentBucket[i][1];
        }
      }
    }
    return undefined;
  }
  delete(key) {
    const address = this.hashMethod(key); // nos genera el indice
    if (this.data[address].length > 1) {
      const newElements = [];
      for (let i = 0; i <= this.data[address].length - 1; i++) {
        if (this.data[address][i][0] !== key) {
          newElements.push(this.data[address][i]);
        }
      }
      this.data[address] = newElements;
    } else {
      this.data[address] = [];
    }
  }
  getAll() {
    this.data.forEach((values, address) => {
      const valEncadenados = values.map(
        ([key, value]) => `[ ${key}: ${value} ]`
      );
      console.log(`${address}: ${valEncadenados}`);
    });
  }
}

const myHashTable = new HashTable(3);
myHashTable.set("mateo", 1998);
myHashTable.set("monica", 1997);
myHashTable.set("ingrid", 2000);
myHashTable.set("alex", 3000);
myHashTable.delete("monica");
myHashTable.getAll();

asi fue como lo implemente y me funciono

//metodo de eliminar una key
    pop(key){
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if(currentBucket){
            for(let i=0; i < currentBucket.length; i++){
                if(currentBucket[i][0] === key){
                    let value = this.get(key);
                    this.data[address].pop([key, value]);
                }
            }
        }
        return this.data[address];
    }

    //recorriendo el hashtable
    foreachArray(){
      for(let i=0; i< myHashTable.data.length; i++){
        if(myHashTable.data[i] != undefined){
            for(let j=0; j< myHashTable.data[i].length; j++){
            console.log(myHashTable.data[i][j]);
            }
        }
      };
    }
class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }

  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    return this.data;
  }
  get(key){
    const address = this.hashMethod(key);
    const currecnkBucked =  this.data[address];
    if(currecnkBucked){
        for(let i = 0; i < currecnkBucked.length; i++){
            if(currecnkBucked[i][0] === key){
                return currecnkBucked[i][1]
            }
        }
    }
    return undefined
  }

  delete(key){
    const address = this.hashMethod(key);
    const currecnkBucked = this.data[address];
    if(currecnkBucked){
        for(let i = 0 ; i <currecnkBucked.length; i++){
            if(currecnkBucked[i][0] === key){
            
                const remove = currecnkBucked[i]
                remove.splice(i,2);
                return remove
            }
        }
    }
    return undefined
  }

  allKey(){
    const key = this.data.map(Element=>
      Element[0][0]
    )
      return key
  }
  
}
const myHashTable = new HashTable(50);

myHashTable.set("pajarito", 1998);
myHashTable.set("pepe", 1990);

Para que no queden espacios vacíos en los buckets, les dejo una solución para eliminar:

delete(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    const deletedItem = currentBucket[i];
                    this.data[address] = currentBucket.filter(item => item[0] !== key);
                    return deletedItem;
                }
            }
        }
        return undefined;
    }

Código de la clase y solución al reto

class HashTable {
  constructor(size) {
    this.data = new Array(size);
    this.keys = []
  }
  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }

  set(key, value) {
    const address = this.hashMethod(key);
    if(!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    this.keys.push(key);
    return this.data;
  }

  get(key) {
    const address =  this.hashMethod(key);
    const currentBucket = this.data[address];

    if(currentBucket[0]) {
      for(let i = 0; i < currentBucket.length; i++) {
        if(currentBucket[i][0] === key) {
          return currentBucket[i][1];
        }     
      }; 
    }
    return undefined;
  }

  deleteElement(key) {
    const address =  this.hashMethod(key);
    const currentBucket = this.data[address];

    if(currentBucket[0]) {
      for(let i = 0; i < currentBucket.length; i++) {
        if(currentBucket[i][0] === key) {
          const deletedElement = currentBucket.splice(i, i + 1);

          if(currentBucket.length < 1) {
            delete this.data[address];
          } 
          this.deleteKey(key);

          return deletedElement;
        }    
      }; 
    }
    return undefined;
  }

  getKeys() {
    return this.keys;
  }
  deleteKey(key) {
    const index = this.keys.indexOf(key);
    this.keys.splice(index, index + 1);
  }
}

const myHashTable = new HashTable(50);

Solución al reto:

  delete(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] == key) {
          const item = currentBucket[i];
          currentBucket.splice(i, 1);
          return item;
        }
      }
    }
    return undefined;
  }

Hola gente.

Dejo por aquí los códigos del reto = ).

delete(key){
        const address = this.hashMethod(key);
        
        let currentBukect = this.data[address];
        for(let i = 0; i < currentBukect.length; i++){
            if(currentBukect[i][0]===key){
                
                delete currentBukect[i];
                return;
            } 
        }     
    }
    getAllkeys(){
        const array = [];
        for(let i = 0; i < this.data.length; i++){
            if(this.data[i]){   
                for(let index = 0; index < this.data[i].length; index++){
                    array.push(this.data[i][index][0]);
                }
            }
        }
        return array;
    }
}

Les dejo mi código es mi idea solo me base en el código de un estudiante para agregarlos keys a un nuevo array

class HashTable {
    constructor(size) {
        this.data = new Array(size);
    }
    hashMethod(key) { 
        let hash = 0;
        for(let i = 0; i < key.length; i++) {
            hash = (hash + key.charCodeAt(i) *i) % this.data.length;
        }
        return hash;
    }
    set(key, value) {
        const address = this.hashMethod(key);
        if(!this.data[address]) {
            this.data[address] = [];
        }
        this.data[address].push([key, value]);
        return this.data;
    }
    get(key){
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if(currentBucket) {
        for(let i = 0; i < currentBucket.length; i++) {
            if(currentBucket[i][0] === key) {
                return currentBucket[i][1];
            }
        }
    }
    return undefined;
    }
    delete(key) {
        const address = this.hashMethod(key);
        delete this.data[address][0];
        delete this.data[address][1];
    }
    listKey(){
        const keys = [];
        for(let i = 0; i <= this.data.length; i++) {
            if(this.data[i]) {
                keys.push(this.data[i][0][0]);
            }
            if(this.data[i] && this.data[i][1]) {
                keys.push(this.data[i][1][0]);
            }
        }  
        return keys;    
    }
    
}
const myHashTable = new HashTable(50);

myHashTable.set('Kenia', 1992);
myHashTable.set('Pedro', 1990);
myHashTable.set('Maria', 1991);
myHashTable.set('Jose', 1993);  
myHashTable.set('Carla', 1994);
myHashTable.set('Elizabeth', 1987);
myHashTable.set('Carlos', 1989);
myHashTable.set('Mariana', 1993);
myHashTable.set('Mara', 1993);
myHashTable.set('Mary', 1993);
myHashTable.listKey();

solucion metodo allkeys del hash espero les ayude

keys(){
        //creo el array de almacenamiento
        let key = [];

        //recorro el hash
        for (let i = 0; i < this.data.length; i++){
            //valido si hay contenido
            if(!this.data[i]) continue;

            //si hay contenido recorro la parte interna
            if(this.data[i]){
                
                for(let j=0;j<this.data[i].length;j++){
                    
                    //agrego los keys 
                    key.push(this.data[i][j][0]);
                }
            }
            
        }
        //retorno los keys del hash
        return key;
    }

este metodo permite devolver tanto todos los keys como todos los values del hashtable

 //return the keys of hash
  getIndex(index = Number) {
    return Object.values(this.data)
      .flat()
      .map((item) => item[index]);
  }

solución del teto para el metodo remove() espero les ayude

//metodo eliminar un elemento
    remove(key){
        //creo el indice a guardar en el array
        const address = this.hasMethod(key);
        
        //asignamos el valor del indice del hash
        const currentBucket = this.data[address]; 
        
        //valido la informacion
        if (currentBucket){

            //busco dentro del array los array iternos 

            for (let i = 0; i < currentBucket.length; i ++){
                //valido que sea igual a la llave
                if (currentBucket[i][0] === key){
                    
                    const deleteItem = this.data[address].splice(i, 1);
                    //metodo splice que corta o elimina desde el indice luego el numero de elementos a eliminar                    
                    //retorno el dato eliminado
                    return deleteItem.flat(); 
                }
            }
        }
    }

Solucion rapida, funciono en unas cuantas pruebas 👍 usenlo bajo su propio riesgo. Si no le entienden yo tampoco 😅

delete(key) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      return undefined;
    }

    const currentBucket = this.data[address].find((item) => item[0] === key);

    if (this.data[address].length === 1) {
      delete this.data[address];
      return currentBucket;
    }

    const index = this.data[address].findIndex((item) => item[0] === key);

    if (index === -1) {
      return undefined;
    }

    this.data[address].shift(index);

    return currentBucket;
  }

  getAllKeys() {
    return this.data.flat().map((item) => item[0]);
  }

//asi me quedo XD

class HashTable {
    constructor() {
        this.data = new Array(50);
    }
    // es lo que hace internamente un hastTable, le asigna aleatoriamente un address a un bucket
    hashMethod(key) {
        let hash = 0;
        for (let i = 0; i < key.length; i++) {
            hash = (hash + (key.charCodeAt(i) * i)) % key.length;
        }
        return hash;
    }
    set(key, value) {
        const address = this.hashMethod(key);
        //sino existe address , se genera un nuevo array.. pero si ya existe se añade el nuevo arreglo a la address ya existente.
        if (!this.data[address]) {
            this.data[address] = [];
        }
        this.data[address].push([key, value]);
        return this.data;
    }
    get(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    return currentBucket[i][1];
                }
            }
        }
        return undefined;
    }
    delete(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    const item = currentBucket[i];
                    currentBucket.splice(i,1);
                    return item;
                }
            }
        }
        return undefined;
    }
    keys() {
        let keys = [];
        for (let i = 0; i < this.data.length; i++) {
            const currentBucket = this.data[i];
            if(currentBucket){
                keys.push(...currentBucket.map(bucket  => bucket[0]))
            }
        }
        return keys;
    }
}

const myHashTable = new HashTable();

Miré que con:

Object.getOwnPropertyNames()

Se puede conseguir todo lo que esté en los objetos.keys

Buenas, les comparto mi código.

Documentación:

class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  hashMethod(key) {
    let hash = 0;
    for (let index = 0; index < key.length; index++) {
      hash = (hash + key.charCodeAt(index) * index) % this.data.length;
    }
    return hash;
  }
  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) this.data[address] = [];
    this.data[address].push([key, value]);
    return this.data;
  }
  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) return currentBucket.filter((el) => el[0] === key)[0][1];
    return undefined;
  }
  keys() {
    return this.data
      .map((element) => element.map((internalElement) => internalElement[0]))
      .flat();
  }
  delete(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    let deleted = undefined;
    if (currentBucket)
      currentBucket.forEach((el, idx) => {
        if (el[0] === key) {
          deleted = this.data[address][idx];
          this.data[address].splice(idx, 1);
        }
      });
    return deleted;
  }
}

const myHashTable = new HashTable(50);

Hola buenas compañeros les dejo mi aporte. Espero que pueda darme feedback 😄 saludos!

delete(key){

        const address = this.hashMethod(key);
        const currentBucket = this.data[address];

        if(currentBucket){

            for(let i = 0; i < currentBucket.length; i++){

                if(currentBucket[i][0] === key){

                    delete this.data[address];
                    return true;
                }
            }
        }
        return false;
    }

    getAllKeys(){

        let dataAll = [];
        for(let i = 0; i < this.data.length; i++){
            if(this.data[i]){
                dataAll.push(this.data[i][0][0]);
            }
        }

        return dataAll.flat(1);
    }

codigo del delete y getAllKeys

getAllKeys() {
    const keys = [];
    this.data.forEach((value) => {
      keys.push(value[0][0]);
    });
    return keys;
  }

  delete(key) {
    const address = this.hashMethod(key);
    const correntBucket = this.data[address];
    if (correntBucket) {
      for (let i = 0; i < correntBucket.length; i += 1) {
        if (correntBucket[i][0] === key) {
          const deleteitem = correntBucket[i][1];
          delete correntBucket[i];
          return deleteitem;
        }
      }
    }
    return undefined;
  }```

Mi código con opciones de formateo

/**
 * Utils
 */

const isTruthy = (element) => element;
const getKey = ([key]) => key;
const mapGetKey = (array) => array.map(getKey);
const label = (title, callback) => {
  console.log("");
  console.log("---------------------------------------");

  console.log("==================================");
  console.log(`======== ${title} ==========`);
  console.log("==================================");

  callback();

  console.log("---------------------------------------");
  console.log("");
};

const hashTableMethodDecorator = (instance, methodDecorated) => {
  const decorator = (...args) => {
    console.log("------------");
    console.log("length before:", instance.data.length);

    const result = instance[methodDecorated](...args);
    console.log(
      `When ${methodDecorated} action was taken, the result was ${result}`
    );

    console.log("length after:", instance.data.length);
    console.log("------------");

    return result;
  };

  return decorator;
};

/**
 * Hash Table Class
 */

class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  _hashMethod(key) {
    // Random number 0 - 65.535 Unicode
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }
  set(key, value) {
    const address = this._hashMethod(key);

    if (!this.data[address]) this.data[address] = [];
    this.data[address].push([key, value]);

    return this.data;
  }

  _getBucket(key) {
    const address = this._hashMethod(key);
    const currentBucket = this.data[address];

    return currentBucket;
  }

  _matchKey(key, currentBucket) {
    for (let i = 0; i < currentBucket.length; i++) {
      const [currentKey] = currentBucket[i];
      if (currentKey === key) return currentBucket[i];
    }
  }

  get(key) {
    const currentBucket = this._getBucket(key);

    if (!currentBucket) return undefined;

    const [_, currentValue] = this._matchKey(key, currentBucket);
    return currentValue;
  }

  delete(key) {
    const address = this._hashMethod(key);
    this.data[address] = undefined;
    return undefined;
  }

  getKeys() {
    return this.data.filter(isTruthy).flatMap(mapGetKey);
  }

  getFormatted(key) {
    const found = this.get(key);
    console.log(`Value received from ${key}: ${exampleHashTable.get(key)}`);
    return found;
  }
}

/**
 * Instance hash table
 */

const exampleHashTable = new HashTable(50);

exampleHashTable.set("daniel", 2000);
exampleHashTable.set("diego", 1990);
exampleHashTable.set("mariana", 1980);
exampleHashTable.set("jonathan", 1999);

/**
 * Delete element
 */

label("Delete element", () => {
  exampleHashTable.getFormatted("daniel");
  hashTableMethodDecorator(exampleHashTable, "delete")("daniel");
  exampleHashTable.getFormatted("daniel");
});

/**
 * Get Keys
 */

label("Get Keys", () => {
  console.log(exampleHashTable.getKeys());
});

Buenas tardes,

comparto reto:

class HashTable {
    constructor(size) {
        this.data = new Array(size);
    }

    // hash funtions (metodo que muy rara vez se tiene que crear)
    hashMethod(key) {
        let hash = 0;
        for (let i = 0; i < key.length; i++) {
            hash = (hash + key.charCodeAt(i) * i) % this.data.length; // generacion de numero random
        }

        return hash;
    }

    // metodo que agrega elementos
    set(key, value) {
        const address = this.hashMethod(key);
        // si no existe un valor crea uno nuevo
        if (!this.data[address]) {
            this.data[address] = [];
        }

        // si ya existe crea una colision con un nuevo arreglo
        this.data[address].push([key, value]);
        return this.data;
    }

    // acceso al elemento
    get(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address]; // indice en donde se encuentra el elemento
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) { // se valida si la key existe
                    return currentBucket[i][1];
                }
            }
        }

        // en caso de no encontarr el bucket retorna undefined
        return undefined;
    }

    // eliminando elemento
    delete(key) {
        const address = this.hashMethod(key);
        if (this.data[address]) {
            delete this.data[address];
            return this.data;
        }

        return undefined;
    }

    // retorno de las key
    returnKey() {
        let keys = [];
        for (let i = 0; i < this.data.length; i++) {
            if (this.data[i]) {
                for (let j = 0; j < this.data[i].length; j++) {
                    keys.push(this.data[i][j][0]);
                }
            }
        }
        return keys;
    }

}

Gracias.

Una opcion de la funcion get() para los que les gusta simplificar codigo.

get(key){
    const address = this.hashMethod(key);
    return this.data[address]?.find((v)=>v[0] == key)[1];
}

No entendi que tipo de output debemos sacar en getAll 🤔

delete(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];

    if (currentBucket.length > 1) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          this.data[address][i] = null;
        }
      }
    } else {
      this.data[address] = null;
    }

    return undefined;
  }

  getAll() {
    const values = this.data.map((hashArray) => hashArray.map((items) => [items[0], items[1]]));

    return values;
  }

Mi método para eliminar en el Hash Table:

  delete (key) {
        const address = this.hashMethod(key);
        if ( !this.data[address] ) return undefined;
        const currentBucket = this.data[address];
    
        const deletedItem = currentBucket.find( item => item[0] === key );
        const indexDeletedItem = currentBucket.indexOf(deletedItem);
        currentBucket.splice(indexDeletedItem,1);
        
        return deletedItem;

    }

Mi aporte a continuación

delete(key){
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if( currentBucket){
            for(let i = 0 ; i < currentBucket.length ; i++){
                if(currentBucket[i][0] === key){
                    delete this.data[address];
                    return currentBucket[i];
                }
            }
        }
        return undefined `The key: ${key}, doesn't exist!`;
    }
returnAllKeys(){
        const keys = [];
        for (let i = 0 ; i < this.data.length ;  i++){
            if(this.data[i]){
                for( let j = 0 ; j < this.data[i].length; j++){
                    keys.push(this.data[i][j][0]);
                }
            }
        }
        return keys;```

Dejo un ejemplo implementado en TypeScript con todos los métodos

En mi caso en el set compruebo si existe el elemento y en caso de que exista sobrescribo el valor, puesto que como lo hace el profesor si el key se repite tendrás varios con el mismo key lo cual no sirve de nada porque luego no podrás acceder a ellos. Haciéndolo de esta manera conseguimos un método con Idempotencia.

const util = require('util');

export class HashTable<K extends string, V> {
  private _length = 0;
  private readonly data: Array<[K, V][]>;
  private readonly size: number;

  constructor(size: number) {
    this.size = size;
    this.data = new Array(size);
  }

  private hash(key: string): number {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash += key.charCodeAt(i);
    }
    return hash % this.size;
  }

  set(key: K, value: V): [K, V][][] {
    const address = this.hash(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    const bucket = this.data[address];
    const element = bucket.find((element) => element[0] === key);
    if (!element) {
      bucket.push([key, value]);
      this._length++;
    } else {
      element[1] = value;
    }
    return this.data;
  }

  get(key: K): V | undefined {
    const address = this.hash(key);
    if (!this.data[address]) return undefined;
    const bucket = this.data[address];
    const element = bucket.find((element) => element[0] === key);
    return (element) ? element[1] : undefined;
  }

  getAll(): [K, V][] {
    const elements: [K, V][] = [];
    this.data.forEach((bucket) => {
      if (bucket) {
        bucket.forEach((element) => {
          elements.push(element);
        });
      }
    });
    return elements;
  }

  getAllKeys(): K[] {
    const keys: K[] = [];
    this.data.forEach((bucket) => {
      if (bucket) {
        bucket.forEach((element) => {
          keys.push(element[0]);
        });
      }
    });
    return keys;
  }

  delete(key: K): V | undefined {
    const address = this.hash(key);
    if (!this.data[address]) return undefined;
    const bucket = this.data[address];
    const element = bucket.find((element) => element[0] === key);
    if (!element) return undefined;
    bucket.splice(bucket.indexOf(element), 1);
    this._length--;
    return element[1];
  }

  get length(): number {
    return this._length;
  }

  [util.inspect.custom]() {
    return this.data;
  }
}

Si os interesa ver más cosas sobre programación esta es mi web donde subo algunos tutoriales https://blog.jcoder.es

Para el Delete, hice lo siguiente, quedo atento a sus aporte 😃

delete(key){
        const address=this.hashMethod(key);
        const currentBucket=this.data[address];
        if(currentBucket){
            for(let i=0;i<currentBucket.length;i++){
            if(currentBucket[i][0]===key){
                    return `Registro [${currentBucket.splice(i,1)}] Eliminado Exitosamente`               
                }
            }
        }
        return undefined
    }

En typescript :

De esta manera resolví HasTable.delete() y HasTable.getAllKeys()
¿Qué opinan?

delete (key) {
    const address = this.hashMethod(key)
    const bucket = this.data[address]
    if (bucket) {
      for (let i = 0; i < bucket.length; i++) {
        if (bucket[i][0] === key) return delete bucket.splice(i, 1)
      }
    }
    return undefined
  }

  getAllKeys () {
    let keys = this.data.flatMap(bucket => {
      if (!bucket) return []
      return bucket.map(record => record[0])
    })

    return keys
  }

Metodo getKeys:

 getKeys() {
        const keys = [];
        for (let i = 0; i < this.data.length; i++) {
            if (this.data[i]) {
                for (let j = 0; j < this.data[i].length; j++) {
                    keys.push(this.data[i][j][0]);
                }
            }
        }
        return keys;
    }

methdo getValues:

 getValues() {
        const values = [];
        for (let i = 0; i < this.data.length; i++) {
            if (this.data[i]) {
                for (let j = 0; j < this.data[i].length; j++) {
                    values.push(this.data[i][j][1]);
                }
            }
        }
        return values;
    }

metodo delete:

 delete(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    currentBucket.splice(i, 1);
                }
            }
        }
        return this.data;
    }

De hecho, otra forma de decirlo es que tenemos un array de tuplas

[ [ key, value ], [ key, value ] ]

Esta fue la forma en que lo hice

delete(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address];
        if(currentBucket) {
            for(let i = 0; i < currentBucket.length; i++) {
                if(currentBucket[i][0] === key) {
                    delete this.data[address];
                    return this.data;
                }
            }
        }
        return undefined;
    }

    getAllKeys() {
        return this.data.filter(set => set.length > 0).map(bucket => bucket[0][0]);
    }

Yo lo entendí así y así lo hice creo que esta bien

class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }
  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    return this.data;
  }
  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          return currentBucket[i][1];
        }
      }
    }
    return undefined;
  }
  delete(key) {
    const address = this.hashMethod(key);
    if (this.data[address]) {
      const deleteValue = this.data[address][0]
      this.data.splice(address, 1)
      return deleteValue
    }
    return undefined
  }
  getAllKeys() {
    for (let i = 0; i < this.data.length; i++) {
      if (this.data[i]) {
        console.log(`Key: ${i} - value: ${this.data[i][0]}`);
      }
    }
  }
}

Les comparto mi solución al método remove(key)…

	remove(key) {
		const address = this.hashMethod(key);
		const currentBucket = this.data[address];
		let currentElement = undefined;
		let index = 0;
		let found = false;
		if (currentBucket) {
			for (let i = 0; i < currentBucket.length; i++) {
				if (found == false && currentBucket[i][0] === key) {
					currentElement = currentBucket[i];
					index = i;
					found = true;
				}
			}
		}
		if(found) {
			this.data[address].splice(index, 1);
			return currentElement;
		}
		return undefined;
	}

<code> 
```    public getAllBucketKeys(key : string) : string[]{
        let bucket : Hash<ValueType>[] = this.get(key)
        let keys : string[] = []
        bucket.map((member : Hash<ValueType>) : void => {
            keys.push(member.key)
        })
        return keys
    }

solución al reto de Remove y getAllKeys

 delete(key)
    {
        let keyFound = this.hashMethod(key);
       
        if(this.data[keyFound])
        {
            const lengthValueHash = this.data[keyFound].length;
            let  valueDelete;
            for(let i =0; i< lengthValueHash; i++)
            {
                if(this.data[keyFound][i][0] === key)
                {
                    valueDelete = this.data[keyFound][i];
                    if(this.data[keyFound].length>1)
                    {
                        delete this.data[keyFound][1];
                    }
                    if(this.data[keyFound].length === 1)
                    {
                        delete this.data[keyFound];
                    }

                }
            }
            return valueDelete;
        }
        return undefined;
       
    }

    getKeys()
    {
        let keys = [];
        for (let i = 0 ; i<this.data.length;i++)
        {
            
            if(this.data[i])
            {
             const element = this.data[i];
             
             for(let index = 0;index< element.length;index++)
             {
                
                keys.push(element[index][0]);
             }
             
              
            }
        }
        return keys;
    }

esta es la manera que hice el get , si no da un index que no existe entonces devuelve null sino pregunta si la longitud es mayor a 1, significa que hay colisión entonces busca los keys y guarda el key si lo encuentra sino directamente devuelve en la posición 1 ;

get(key){
        let keyFound = this.hashMethod(key);
        let indexValue = 0;
       
        if(this.data[keyFound])
        {
            const lengthValueHash = this.data[keyFound].length;
            if(lengthValueHash > 1)
            {
                for(let i =0; i< lengthValueHash; i++)
                {
                  if(this.data[keyFound][i][0] === key)
                  {
                    indexValue = i;
                  }
                }
            }
            return this.data[keyFound][indexValue][1];
        }
        return null;
       
       
    }

class HashTable {
constructor(size){
this.data =new Array(size);
}

hashMethod(key) {
    let hash = 0;
    for(let i = 0; i < key.length; i++){
        hash = (hash +key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
}

set(key,value){
    const address =this.hashMethod(key);
    if(!this.data[address]){
        this.data[address] =[];
    }
    this.data[address].push([key, value]);
    return this.data;
}

get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if(currentBucket){
        for(let i = 0; i < currentBucket.length; i++){
            if(currentBucket[i][0] === key){
                return currentBucket[i][1];
            }
        }
    }
    return undefined;

}

delete(key){
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if(currentBucket){
        const value = currentBucket[0];
        currentBucket.splice(currentBucket,1);
        return value;

    }
    return undefined;
    
}

listarKeys(){
     var value = [];
     
    for(let i = 0; i < this.data.length; i++){
        if(this.data[i]){
            value.push(this.data[i][0][0])
        }
       
    }
    return value;

}

}

const myHashTable = new HashTable(50);

Elimina un item especifico segun su key

deleteItem(key){
    const address = this.hashMethod(key);
    if(this.data[address]){
      delete this.data[address];
    }else console.log("Not found");
    return this.data;
  }

Devuelve las entradas con su informacion almacenadas en el bucket

getAllKey(){
      const addresses = this.data.length;
      for(let i = 0; i < addresses; i++){
        if(this.data[i] != null){
          console.log(this.data[i][0]);
        }
      }
  }

Esta es mi implementación de getAllKeys y remove,

class hashTable {
    constructor(size){
        this.data = new Array(size);
    }

    hashMethod(key){
        let hash = 0;
        for (let i = 0; i < key.length; i++){
            hash = (hash + key.charCodeAt(i)*i) %this.data.length;
        }
        return hash;
    }

    set(key,value){
        const address = this.hashMethod(key);
        if(!this.data[address]){
            this.data[address] = [];
        }
        this.data[address].push([key,value]);
        return this.data
    }

    get(key){
        const address = this.hashMethod(key);
        const arrayIn = this.data[address];
        if(arrayIn != null){
            for (let i = 0; i<arrayIn.length; i++){
                if (key === arrayIn[i][0]){
                    return arrayIn[i];
                }
            }
        }

        return undefined;
    }


    getAllKeys(){
        const allKeys = []
        for (let i = 0;i<this.data.length;i++){
            const arrayIn = this.data[i];
            if (arrayIn){
                for (let j = 0;j<arrayIn.length;j++){
                    allKeys[allKeys.length] = arrayIn[j][0];
                }                
            }
        }
        return allKeys;
    }

    remove(key){
        const address = this.hashMethod(key);
        const arrayIn = this.data[address];
        if(arrayIn){
            if(arrayIn.length == 1){
                delete this.data[address]
            }
            else{   
                for (let i = 0; i<arrayIn.length; i++){
                    if (key === arrayIn[i][0]){
                        for (let j = 0; j<arrayIn.length-1-i;j++){
                            this.data[address][i] = this.data[address][i+1]; 
                        } 
                    }
                }
                this.data[address].pop();

            }
        }
        return undefined;
    }
}

const myNewArray = new hashTable(50); 

Yo llamo arrayIn a lo que en el video nombran como currentBucket porque ya lo había hecho y me dió flojera cambiarlo, saludos!

My code

	delete(key) {
		const address = this.hashMethod(key);
		delete this.data[address];
	}

	getAll() {
		const allKeys = [];
		for (const key in this.data) {
			if (Object.hasOwnProperty.call(this.data, key)) {
				allKeys.push(this.data[key]); 
			}
		}
		return allKeys.flat();
	}

Dejo la solución del reto

delete(key)
  {
    const address = this.hashMethod(key)
    const currentBucket = this.data[address]
    if(currentBucket)
    {
      if(currentBucket.length > 1)
      {
        for(let i=0; i< currentBucket.length; i++)
        {
          if(currentBucket[i][0] === key)
          {
            this.data[address].splice(i,1)
            return key
          }
        }
      }
      this.data[address].shift()
      return key
    }
    return undefined
  }


getKeys()
  {
    const keys = []
    for(let i=0; i<this.data.length; i++)
    {
      if(this.data[i])
      {
        if(this.data[i].length>1)
        {
          for(let j=0; j<this.data[i].length;j++)
          {
            keys.push(this.data[i][j][0])
          }
        }
        else keys.push(this.data[i][0][0])
      }
    }
    return keys
  }

Asi lo hice yo

delete(key){
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    let deleted;
    if(currentBucket){
        if(currentBucket.length > 1){
            for(let i = 0; i< currentBucket.length; i++){
                if(currentBucket[i][0] === key){
                    deleted = currentBucket[i];
                    for(let idx = i; idx < currentBucket.length; idx++){
                        currentBucket[idx] = currentBucket[idx + 1];
                    }
                    currentBucket.pop();
                    return deleted;
                }
            }
        }
        deleted = currentBucket[0];
        delete currentBucket[0];
        return deleted;
    }
    return undefined;
}
clear(){
    this.data = new Array(this.size);
    return this.data;
}
¿Para que se usan? Las tablas de has son estructuras de datos asociativos y se usan principalmente para almacenar grandes volúmenes de información de manera que puedan ser accedidos de una forma más rápida. Dependiendo del algoritmo de hash utilizado son más o menos efectivos.

Comparto el Get para todos las key, vi soluciones complicadas, capaz la mia no es muy practica pero es más sencilla a las que vi:

getKeys(){
        var keys=[]
        for ( let i=0 ; i<=this.data.length ; i++ ) {
            if ( this.data[i] != undefined ) {
            keys.push( this.data[i] );
            }
        }
        return keys;
    }

Aqui esta mi codigo con el metodo delete. El unico detalle que encontre en esta clase es que pasa cuando quieres sobre escribir un valor, habria que crear un metodo update pues con el set no se puede a menos que se modidifique pero veo que serian demasiados pasos.
Tu que piensas?

class HashTable {
	constructor(size) {
		this.data = new Array(size);
	}
	hashFunctioner(key) {
		let hash = 0;
		for (let i = 0; i < key.length; i++) {
			hash = (hash + key.charCodeAt(i) * i) % this.data.length;
		}
		return hash;
	}
	setter(key, value) {
		const address = this.hashFunctioner(key);
		console.log(address);
		if (!this.data[address]) {
			this.data[address] = new Array();
		}
		this.data[address].push([key, value]);
		return this.data;
	}
	getter(key) {
		const address = this.hashFunctioner(key);
		const bucket = this.data[address];
		if (bucket) {
			for (let i = 0; i < bucket.length; i++) {
				if (bucket[i][0] === key) {
					return bucket[i][1];
				}
			}
		}
		return null;
	}
	deleter(key) {
		const address = this.hashFunctioner(key);
		const bucket = this.data[address];
		if (bucket) {
			for (let i = 0; i < bucket.length; i++) {
				if (bucket[i][0] === key) {
					bucket.splice(i, 1);
					return bucket;
				}
			}
		}
		return null;
	}
}
  delete(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          this.data[address].splice(i, 1);
          return true;
        }
      }
    }
    return false;
  }
  getKeys() {
    const keys = [];
    for (let i = 0; i < this.data.length; i++) {
      if (this.data[i]) {
        for (let j = 0; j < this.data[i].length; j++) {
          keys.push(this.data[i][j][0]);
        }
      }
    }
    return keys;
  }

Holaaa, les dejo mi resolucion del reto.

//Meotdos para encontrar, eliminar,etc todos los datos

class HashTable {
    constructor(size){
        this.data = new Array(size);
    }
    //Las hashFucntion no las tenes que hacer, la realiad es que ya existen en github o google, una de ellas es la que tengo aca abajo,peero, lo mejor es googlear la mejor que se adapte a mi estilo.
    hashMethod(key) {
        let hash = 0;
        for(let i = 0; i < key.length; i++) {
            hash = (hash + key.charCodeAt(i) * i) % this.data.length;
        }
        return hash;
    }
    set(key,value){
        const address = this.hashMethod(key);
        if(!this.data[address]) {
            this.data[address] = [];
        } 
        this.data[address].push([key,value]);
        return this.data;
    }
    get(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address]
        if(currentBucket) {
            for(let i = 0; i < currentBucket.length; i++) {
                if(currentBucket[i][0] === key){
                    return currentBucket[i][1]
                }
            }
        }
    }
    delete(key) {
        const address = this.hashMethod(key);
        const currentBucket = this.data[address]
        if(currentBucket) {
            for(let i = 0; i < currentBucket.length; i++) {
                if(currentBucket[i][0] === key){
                  console.log(currentBucket)
                  
                 const inndex = currentBucket.indexOf(currentBucket[i])
                  console.log(inndex)
                  const deleted = currentBucket.splice(inndex,1)
                  console.log(currentBucket) 
                    
                }
            }
        }
    }
		getKeys(){
     const keys = []
     const concat = this.data.flat(1)
     console.log(concat)
     for(let i = 0; i < concat.length;i++) {
    		keys.push(concat[i][0])
  
     }
     console.log(keys)
   }

}



//address es el numero que genera la funcion hash con la key.
//key es la palabra que guardaremos
//value es un valor de lo que nos guste guaradar

const myHashTable = new HashTable(50);
myHashTable.set('Diego',2001)
myHashTable.set('Mariana',1342)
myHashTable.get('Mariana')
myHashTable.delete('Mariana')

Impresionante clase, me encanta

No lo se Rick, obtener el valor de un HashTable tiene una complejidad de O(1) y aquí parece O(n)

Aqui el codigo un poco mas pequeño utilizando la webAPI de find

get(key){
    const address = this.hashMethod(key)
    const currentBucket = this.data[address]

    if(currentBucket){
        const value = currentBucket.find(item => item[0] === key)
        return value[1]
    }
    return undefined;
}

Metodos Borrrar y llavesObjetos!

class HashTable {
  constructor(size) {
    this.data = new Array(size);
  }
  hashMethod(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash = (hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }
  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      this.data[address] = [];
    }
    this.data[address].push([key, value]);
    return this.data;
  }
  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if (currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          return currentBucket[i][1];
        }
      }
    }
    return undefined;
  }

  borrar(key){
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if(currentBucket){
      for(let i = 0 ; i < currentBucket.length; i++){
        if(currentBucket[i][0] === key){
          delete this.data[address];
          return currentBucket
        }
      }
    }
    return undefined
  }
  llavesObjeto() {
    const keys = [];
    for(let i = 0; i < this.data.length ; i++){
      if(this.data[i]){
        for(let e = 0; e < this.data[i].length ; e++){
          keys.push(this.data[i][e][0])
        }
      }
    }
    return keys;
  }
}

Mi código:
Me hubiera gustado no haber usado el método “splice”, pero no supe cómo hacer el “delete” y que el tamaño del array de keys con el mismo hash se redujera. COMENTARIOS POR FAVOR!

delete(key) {
  const address = this.hashMethod(key)
  const currentBucket = this.data[address]
  if (currentBucket) {
    for (let i = 0; i < currentBucket.length; i++) {
      if (currentBucket[i][0] === key) {
        currentBucket.splice(i, 1)
        return key
      }
    }
  }
  return false
}

getKeys() {
  return this.data.reduce((keysArray, values) => {
    const keys = values.map(([key]) => key);
    return keysArray.concat(keys)
  }, []);
}

Creo que el método “delete” no debería devolver el “value” por el principio de responsabilidad única. Estamos programando un delete, no un get(key).

Delete method:

  remove(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];

    if (currentBucket) {
      if (currentBucket.length > 1) {
        for (let i = 0; currentBucket.length; i++) {
          if (currentBucket[i][0] === key) {
            const value = currentBucket[i];
            currentBucket.splice(i, 1);
            return value;
          }
        }
      }
      if (currentBucket.length === 1) {
        const index = this.data.indexOf(currentBucket);
        this.data.splice(index, 1);
      }
    }
  }

Este man es muy inteligente 🤯

Aquí mi solución para los desafíos (son los métodos al fondo de la class, “delete()” y “getKeys()”):

class HashTable{
    constructor(size){
        this.data = new Array(size)
    }
    hashMethod(key){
        let hash = 0
        for(let i = 0; i < key.length; i++){
            hash = (hash + key.charCodeAt(i) * i) % this.data.length
        }
        return hash
    }

    set(key, value){
        const address = this.hashMethod(key)
        if(!this.data[address]){
            this.data[address] = []
        }
        this.data[address].push([key, value])
        return this.data
    }

    get(key){
        const address = this.hashMethod(key)
        const currentBuket = this.data[address]
        if(currentBuket){
            for(let i = 0; i < currentBuket.length; i++){
                if(currentBuket[i][0] === key){
                    return currentBuket[i][1]
                }
            }
        }
        return undefined
    }
    delete(key){
        const address = this.hashMethod(key)
        const currentBuket = this.data[address]
        let valueKey
        if(currentBuket){
            for(let i = 0; i < currentBuket.length; i++){
                if(currentBuket[i][0] === key){
                    valueKey = currentBuket[i]
                    currentBuket.splice(i, 1)
                }
            }
        }
        console.log(currentBuket.length, currentBuket)
        return valueKey
    }

    getKeys(){
        const allKeys = []
        for(let i = 0; i < this.data.length; i++){
            const keyType = this.data[i]
            console.log(keyType)
            if(Array.isArray(keyType) && this.data[i].length > 0){
                for(let indx = 0; indx < keyType.length; indx++){
                    allKeys.push(keyType[indx][0])
                }
            }
        }
        return allKeys
    }
}

Listo el reto de la clase, me gusto, me hizo pensar en las estructuras y usar otras cosas que no fueran los clásicos métodos que ofrece JavaScript

class hashTable {
  constructor() {
    this.data = Array(50);
  }
  hashMethod(key) {
    let hash = 0; 
    for (let i = 0; i < key.length; i++) {
      hash = ( hash + key.charCodeAt(i) * i) % this.data.length;
    }
    return hash;
  }
  set(key, value) {
    const address = this.hashMethod(key);
    if (!this.data[address]) {
      this.data[address] = []
    }
    this.data[address].push([key, value]);
    return this.data;
  }
  get(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if(currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          return currentBucket[i][1];
        } 
      }
    }
    return undefined;
  }
  delete(key) {
    const address = this.hashMethod(key);
    const currentBucket = this.data[address];
    if(currentBucket) {
      for (let i = 0; i < currentBucket.length; i++) {
        if (currentBucket[i][0] === key) {
          const item = `[${currentBucket[i][0]}: ${currentBucket[i][1]}] Deleted`
          delete currentBucket[i][0];
          delete currentBucket[i][1];
          return item;
        } 
      }
    }
    return "Not exist";
  }
  getAll() {
    const finded = []
    for (let i = 0; i < 50; i++) {
      const currentBucket = this.data[i]
      if(currentBucket) {
        for (let i = 0; i < currentBucket.length; i++) {
          if (currentBucket[i][0]){
            finded.push([currentBucket[i][0], currentBucket[i][1]])
          }
        }
      }
      
    }
    return finded
  }
}

const myHashTable = new hashTable();

myHashTable.set("Juan", 1990);
myHashTable.set("Elizabeth", 1996);
myHashTable.set("Diego", 1994);
myHashTable.set("Jose", 2000);
myHashTable.set("Juan", 1985);
myHashTable.set("Mariana", 1998);

myHashTable.get("Diego");

myHashTable.delete("Diego");

myHashTable.getAll();

Hola 😀.
Les comparto mi solución de los dos retos que nos han dejado. Gracias por su atención !

// Delete an element 

  deleteElement( key )
  {
    const address = this.hashMethod(key)
    const currentBucket = this.data[address]

    if(currentBucket)
    {
      for ( let i = 0 ; i < currentBucket.length ; i++ )
      {
        if( currentBucket[i][0] === key )
        {
          delete currentBucket[i]
        }
      } 
    }
    return undefined
  }

  // Return all the keys
  getAllKeys()
  {
    let listOfKeys = [  ]
    for ( let i =  0 ; i < this.data.length - 1 ; i++ )
    {
      if( this.data[i] !==  undefined )
      {
        for( let l = 0 ; l < this.data[i].length ; l++ )
        {
          listOfKeys.push( this.data[i][l][0] )
        }
      }
    }
    return listOfKeys
  }

Esta es una propuesta de la clase HashTable, junto con los métodos getAllKeys y delete 👇

class HashTable {

    constructor(size) {
        this.data = new Array(size);
    }

    hashMethod(key) {
        let hash = 0;
        for (let i = 0; i < key.length; i++) {
            hash = (hash + key.charCodeAt(i) * i) % this.data.length;
        }
        return hash;
    }

    set (key, value) {
        const address = this.#getAddress(key);
        if (!this.data[address]) {
            this.data[address] = [];
        }
        this.data[address].push([key, value]);
    }

    get (key) {
        const currentBucket = this.#getCurrentBucket(key);
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] == key) {
                    return currentBucket[i][1];
                }
            }
        }
        return undefined;
    }

    delete (key) {
        const currentBucket = this.#getCurrentBucket(key);
        if (currentBucket) {
            for(let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    const item = currentBucket[i];
                    //delete currentBucket[i];
                    currentBucket.splice(i,1);
                    return item;
                }
            }
        }
        return undefined;
    }

    getAllKeys() {
        const keys = [];
        let key;
        let bucket;
        for(let i = 0; i < this.data.length; i++) {
            bucket = this.data[i];
            if (bucket) {
                for(let j = 0; j < bucket.length; j++) {
                    key = bucket[j];
                    if (key) {
                        console.log(key);
                        keys.push(key[0])
                    }
                }
            }
        }
        return keys;
    }

    #getAddress (key) {
        return this.hashMethod(key);
    }

    #getCurrentBucket (key) {
        const address = this.#getAddress(key);
        const currentBucket = this.data[address];
        return currentBucket;
    }
}

const myHashTable = new HashTable(50);

// TEST
myHashTable.set("Sandro", 1967);

console.log(myHashTable.data);

myHashTable.set("Mariana", 1997);
myHashTable.set("Diego", 2000);

console.log(myHashTable.data);

console.log(myHashTable.get("Sandro"));
console.log(myHashTable.get("Mariana"));
console.log(myHashTable.get("Diego"));
console.log(myHashTable.get("Julian"));

console.log(myHashTable.delete("Diego"));
console.log(myHashTable.data);

console.log(myHashTable.getAllKeys());
/*Es el mismo aporte de la clase pasada, con el plus que nuestro intento de comprobacion dedujo el metodo get de esta clase*/
class HashTable {
    constructor(size) {
        this.data = new Array(size)
    }
    hashMethod(key) {
        let hash = 0;
        for (let i = 0; i < key.length; i++) {
            hash = (hash + key.charCodeAt(i) * i) % this.data.length;
        }
        return hash
    }
    set(key, value) {
        const address = this.hashMethod(key)
        if (!this.data[address]) {
            this.data[address] = []
        }
        this.data[address].push([key, value])
        return this.data
    }
    //IMPLEMENTACION DEL GET DEDUCIDO DE FORMA SIMPLE
    // get(key) {
    //     const address = this.hashMethod(key)
    //     return this.data[address]
    // }
    //LA FORMA EXACTA PARA IDENTIFICAR EL VALOR PRECISO
    get(key) {
        const address = this.hashMethod(key)
        const currentBucket = this.data[address]
        if (currentBucket) {
            for (let i = 0; i < currentBucket.length; i++) {
                if (currentBucket[i][0] === key) {
                    return currentBucket[i][1]
                }
            }
        } else {
            return undefined
        }
    }
}

//Generamos 50 buckets
const myHashTable = new HashTable(50)
// console.log(myHashTable)
myHashTable.set("Diego", 1990)
myHashTable.set("Mariana", 1998)
myHashTable.set("Alejandra", 2000)
// const address = myHashTable.hashMethod("Diego")
// console.log(myHashTable.data[address])
// console.log(myHashTable.data[10])
/**La funcion get se dedujo al tratar de comprobar como mi comentario de la clase pasada */
console.log(myHashTable.get('Diego'))
// console.log(myHashTable)