Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codeserk/253b6b61cc689e40160fa3bb041bdb45 to your computer and use it in GitHub Desktop.
Save codeserk/253b6b61cc689e40160fa3bb041bdb45 to your computer and use it in GitHub Desktop.
Design a hashmap without using any built-in libraries. You should include the following functions
interface MapItem<T> {
readonly key: string,
readonly value: T
}
/** HashMap implementation using a 2D array */
class ArrayHashMap<T> {
/**
* Buckets where data will be stored
*
* <key hash % max> => [ <item1>, <item2>, ..., <itemN> ]
*/
protected readonly buckets: MapItem<T>[][] = []
/**
* Constructor.
* @param bucketSize Size of the array, greater means less collisions.
*/
constructor(protected readonly bucketSize: number = 1000) {}
/**
* Gets a value from the map.
* @param key
* @returns value if found, -1 otherwise.
*/
get(key: string): T | -1 {
const bucket = this.getBucket(key)
const item = bucket.find(item => item.key === key)
return item !== undefined ? item.value : -1
}
/**
* Adds a new value to the map, replaces it if it existed.
* @param key
* @param value
*/
put(key: string, value: T): void {
const bucket = this.getBucket(key)
for (const item of bucket) {
if (item.key === key) {
item.value = value
return
}
}
const index = this.getBucketIndex(key)
bucket.push({ key, value })
this.buckets[index] = bucket
}
/**
* Removes a key from the map.
* @param key
*/
remove(key: string): void {
const index = this.getBucketIndex(key)
const updatedBucket = this.getBucket(key).filter(item => item.key !== key)
this.buckets[index] = updatedBucket
}
/**
* Gets the bucket where the key should be present.
* @param key
* @returns bucket or empty array if the key is not present.
*/
protected getBucket(key: string): MapItem<T>[] {
const index = this.getHash(key) % this.bucketSize
return this.buckets[index] || []
}
/**
* Gets the bucket index from a key, ensures the index is not outside the
* boundaries of the array. (ha, as if that mattered at all here).
* @param key
* @returns index
*/
protected getBucketIndex(key: string): number {
return this.getHash(key) % this.bucketSize
}
/**
* Gets a hash from a string,
* unsurprisingly, I took this from Stack-overflow (:
* @param key
* @returns numeric hash from a string
*/
protected getHash(key: string): number {
return key.split('').reduce((result: number, char: string) => {
result = (result << 5) - result + char.charCodeAt(0)
return result & result
}, 0)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment