No hay una única forma correcta de crear una Hash Table en JS, realmente lo que tenemos que tener en cuenta es cual es la funcionalidad de esta estructura de datos y partiendo de ahí se pueden proponer distintas soluciones, en este tutorial voy a presentar solamente una de tantas soluciones que hay.
<h1>¿Qué es y para que sirve una Hash Table?</h1>Funcionan de una manera similar a los objetos literales de JS, pero la diferencia mas significativa es que hay un hash que funciona como address, para que desde ahí podamos acceder a la información que vayamos guardando en la Hash Table.
<h1>¿Qué es un hash y como crear uno en JS?</h1>Vamos a entrar en materia de una vez. Lo primero que tenemos que saber (y en lo que se basan las Hash Tables) es el uso de los hashes y como podemos crear uno en JS.
En general, un hash es una secuencia de números y letras que nos permiten identificar un dato, ya que se supone que este dato es único. En otras palabras, el hash funciona como token para que podamos identificar información de manera rápida y segura, ya que no puede haber dos hashes iguales. Los hashes son utilizados en las bases de datos para encriptar las contraseñas de los usuarios y que el personal encargado de manejar las bases de datos no puedan acceder a el perfil de cierto usuario.
Es mas que nada una manera de garantizar seguridad.
Como dato curioso, la encriptación y los hashes son la base del mundo de las cripto monedas, tokenization, etc… Aunque el nombre per se es auto descriptivo (cripto… monedas), para alguien sin este conocimiento, no es nada obvio
Lenguajes que funcionan del lado del backend tienen funciones para crear hashes de acuerdo a diferentes algoritmos. En el caso de JS, no existen funciones que hagan eso por nosotros, pero hay maneras de crear hashes que nos puedan ayudar para hacer este ejercicio.
Solo para que estés un poco mas familiarizado con la forma de un hash, estos pueden verse de la siguiente manera:
En nuestro caso no vamos a hacer algo tan complejo, mas bien, vamos a hacer algo muy sencillo, pero que al final nos va a dar una secuencia de números muy parecida a un hash que se puede usar en el mundo real.
hashFunction(key) {
const splittedWord = key.toLowerCase().split("");
const codes = splittedWord.map((letter) => String(letter).charCodeAt(0));
return codes.join("");
}
Lo que hace la función es muy sencillo, toma como parámetro una key, que tiene que ser un string y regresa un numero.
La constante splittedWord lo que hace es romper el string en un array, para después poder manipular cada letra.
La constante codes transforma ese array de letras por otro array de códigos. Ahora, la WebAPI charCodeAt
lo que hace es regresarnos el código de cada character que le estamos pasando.
Por ultimo, unimos los código de los caracteres con join y listo.
Veamos un ejemplo de lo que tendríamos que ver en esta función:
lethash1 = hashFunction("Mandarinas");
console.log(hash1) // 109971101009711410511097115
Eso es mas o menos lo que tendríamos que obtener como resultado. Es un hash de puros números. Te reto a hacer una de números y letras, para aumentar la complejidad. Aunque OJO, cada que pasemos como parámetro el mismo string, necesitamos tener el mismo hash como resultado.
<h1>¿Ya tenemos el hash, ahora qué?</h1>Lo que sigue, después de hacer lo “mas difícil”, es crear la clase HashTable para ahora si crear una hash table de verdad.
class hashTable {
constructor() {
this.content = [];
}
hashFunction(key) {
const splittedWord = key.toLowerCase().split("");
const codes = splittedWord.map((letter) => String(letter).charCodeAt(0));
return codes.join("");
}
add(key, value) {
const address = this.hashFunction(key);
const row = {
address: address,
key: key.toLowerCase(),
value: value
};
this.content.push(row);
}
get(key) {
const address = this.hashFunction(key);
returnthis.content.find((hash) => hash.address === address);
}
}
La manera en la que yo realice el ejercicio fue creando un array y agregando rows o filas para poder llenar esta hash table.
Este es el código mas básico para poder crear un hash table, De aquí te reto a dos cosas:
Version mas robusta del hashTable
class hashTable { constructor(...args) { this.content = []; if (args.length) { args.forEach((arg) => this.insert(arg.key, arg.value)); } } hashFunction(key) { const splittedWord = key.toLowerCase().split(""); const codes = splittedWord.map( (letter) => `${letter}${String(letter).charCodeAt(0)}` ); return codes.join(""); } insert(key, value) { let comprobation = this.search(key); if (comprobation) { thrownew Error( `${key} is already declared in the table. Choose another key` ); } else { const address = this.hashFunction(key); const row = { address: address, key: key.toLowerCase(), value: value }; this.content.push(row); } } search(key) { const address = this.hashFunction(key); return this.content.find((hash) => hash.address === address); } delete(key) { const comprobation = this.search(key); if (comprobation) { const index = this.content.findIndex( (hash) => hash.key == key.toLowerCase() ); this.content.splice(index, 1); } else { thrownew Error(`${key} does not exist in the table`); } } }