Мы часто используем хэштаблируемые/карты/словаря для хранения данных, поскольку они обеспечивают быстрый поиск на O (1). Даже массивы предоставляют o (1) поиск, но только если вы знаете об индексе элемента, к которому вы пытаетесь получить доступ, в противном случае вам нужно пройти через массив и проверить каждый элемент, чтобы наконец найти совпадение, тем самым создавая сложность времени o (n). В JavaScript даже объекты похожи на карты, так как даже они хранят данные в парах ключевых значений, но единственное отличие-это может иметь только строки в качестве ключей, тогда как карты могут иметь какой-либо тип данных в качестве ключа. Давайте внедрим нашу собственную хэш -таблицу. Для этого мы объявим класс JavaScript с конструктором.
class HashTable {
constructor(size){
this.data = new Array(size);
}
Как мы знаем для O (1) поиска, нам нужно сохранить пару ключевых значений в определенном индексе в этом массиве, чтобы мы могли получить то же самое, используя этот индекс. Таким образом, всякий раз, когда мы вставляем в хэштату пару клавишных значений, ключ передается в хэш-функцию, которая генерирует местоположение индекса массива, где будет храниться ключ. Эта конкретная хеш -функция должна быть идентификационной хеш -функцией, что означает, что заданный вход всегда будет генерировать один и тот же выход. (Пример: если он генерирует 104 для «манго», то он всегда будет генерировать 104 для «манго», выход не будет изменяться с течением времени). Давайте внедрим функцию хэш, я использую приведенную ниже логику, которую вы можете использовать любую логику хеширования, которую вы пожелаете.
hash(key) {
let hash = 0;
for (let i =0; i < key.length; i++){
hash = (hash + key.charCodeAt(i) * i) % this.data.length
}
return hash;
}
Ребята из Java могут сделать эту хэш -функцию частной, так как это будет использоваться только внутри. Заметьте, что мы используем % this.data.length так что значение хэша, которое будет использоваться в качестве индекса массива списка this.data Превышает длину this.data . Теперь давайте используем эту функцию хэш для вставки паров ключевых значений в нашу хэштату, внедрив метод SET. Этот метод принимает два параметра, а именно ключ и значение, в которых ключ передается в хэш -функцию, которая генерирует число, которое является индексным положением this.data множество и мы будем хранить эту пару клавишных значений в качестве массива в месте индекса, т.е. [ключ, значение] в this.data [hashvalueofkey] Анкет
set(key, value) {
let address = this.hash(key);
if (!this.data[address]) {
this.data[address] = [];
}
this.data[address].push([key, value]);
return this.data;
}
Здесь мы рассчитываем хэш для ключа, проверяем, существует ли что-то в этом расчетном хэш-индексе этого массива, если нет, то мы создаем массив в этом индексе, помещайте пару ключевых значений в него. Если индекс массива уже содержит массив пар клавишных значений, мы нажимаем новый массив пар клавишных значений внутри массива, присутствующего в этом индексе this.data . Наконец, давайте реализуем функцию GET, которая принимает ключ в качестве параметра, и извлекает значение, которое мы вставили вместе с этим ключом. Сначала в этой функции мы рассчитываем хэш для ключа, передаваемого, поскольку наша функция хэш является идентификационной функцией, поэтому она будет генерировать то же значение (индекс this.data ), которая была сгенерирована во время введения ключа- Пара значений в случае установленного метода. Тогда, если мы найдем массив, который в сгенерированном индексе Место this.data Затем мы перечитываем этот массив (этот массив содержит массивы, в которых есть два элемента, ключ и значение т.е. [ключ, значение]) и проверьте, соответствует ли клавиша нашу функцию GET первым элементом любого из субррей, поскольку первый элемент является ключом, а второй элемент – это значение. Если мы найдем совпадение, то возвращаем второй элемент, то есть значение этого массива, иначе мы возвращаем неопределенные.
get(key){
const address = this.hash(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;
}
Таким образом, мы внедрили хэштату с вставкой и поиском O (1), ниже приведен полный код
class HashTable {
constructor(size){
this.data = new Array(size);
}
hash(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) {
let address = this.hash(key);
if (!this.data[address]) {
this.data[address] = [];
}
this.data[address].push([key, value]);
return this.data;
}
get(key){
const address = this.hash(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('grapes', 10000)
myHashTable.get('grapes')
myHashTable.set('apples', 9)
myHashTable.get('apples')
Оригинал: “https://dev.to/avishkardalvi/your-own-hashtable-dictionary-map-in-javascript-4kk2”