// https://github.com/TheOdinProject/curriculum/issues/27103 class Node { constructor(key, value) { this.key = key; this.value = value; this.next = null; } } class LinkedList { constructor() { this.size = 0; this.head = null; this.tail = null; } append(key, value) { let newNode = new Node(key, value); if (this.head == null) { this.head = newNode; } else { const temp = this.head; this.head = newNode; this.head.next = temp; } if (this.tail == null) { this.tail = newNode; } this.size += 1; } pop() { if (this.head.next == null) { this.head = null; this.tail = null; } else { this.head = this.head.next; } this.size -= 1; } contains(key) { function searchNodes(node, key) { if (node.key === key) { return true; } else if (node.next == null) { return false; } else { return searchNodes(node.next); } } return searchNodes(this.head, key); } replace(key, value) { function replace(node) { if (node.key === key) { node.value = value; } else { return replace(node.next); } } replace(this.head, key); } find(key) { function searchNodes(node, key) { if (node.key === key) { return node.value; } else if (node.next == null) { return null; } else { return searchNodes(node.next, key); } } return searchNodes(this.head, key); } remove(key) { let lastNode = this.head; let currentNode = this.head; if (currentNode.key === key) { if (currentNode.next == null) { this.size = 0; this.head = null; this.tail = null; } else { this.size -= 1; this.head = this.head.next; } return true; } while (currentNode) { if (currentNode.key === key) { lastNode.next = currentNode.next; this.size -= 1; return true; } lastNode = currentNode; currentNode = currentNode.next; } return false; } } class HashMap { constructor(capacity = 8) { this.initialCapacity = capacity; this.capacity = capacity; this.buckets = Array(capacity); this.capacity = this.buckets.length; this.loadFactor = 0.75; } stringToNumber(string) { let hashCode = 0; const primeNumber = 31; for (let i = 0; i < string.length; i++) { hashCode = primeNumber * hashCode + string.charCodeAt(i); } return hashCode; } hash(key) { return this.stringToNumber(key); } capacityWatcher() { let consumed = this.buckets.filter(Object).length; if (consumed >= this.capacity * this.loadFactor) { this.capacity = Math.round(1.25 * this.capacity); } } set(key, value) { let _hash = this.hash(key); let bucketIndex = _hash % this.capacity; this.capacityWatcher(); if (this.buckets[bucketIndex] == undefined) { let linkedList = new LinkedList(); linkedList.append(key, value); this.buckets[bucketIndex] = linkedList; } else { let keyExists = this.buckets[bucketIndex].contains(key); if (keyExists) { this.buckets[bucketIndex].replace(key, value); } else { this.buckets[bucketIndex].append(key, value); } } } get(key) { for (let i = 0; i < this.buckets.length; i++) { if (this.buckets[i]) { let value = this.buckets[i].find(key); if (value) return value; } } } has(key) { for (let i = 0; i < this.buckets.length; i++) { if (this.buckets[i]) { let value = this.buckets[i].find(key); if (value) return true; } } return false; } remove(key) { for (let i = 0; i < this.buckets.length; i++) { if (this.buckets[i]) { let removed = this.buckets[i].remove(key); if (this.buckets[i].size === 0) this.buckets[i] = undefined; if (removed) return true; } } return false; } length() { let count = 0; for (let i = 0; i < this.buckets.length; i++) { if (this.buckets[i]) { count += this.buckets[i].size; } } return count; } clear() { this.capacity = this.initialCapacity; this.buckets = Array(this.capacity); } keys() { let _keys = []; for (let i = 0; i < this.buckets.length; i++) { if (this.buckets[i]) { let currentNode = this.buckets[i].head; while (currentNode) { _keys.push(currentNode.key); currentNode = currentNode.next; } } } return _keys; } values() { let _values = []; for (let i = 0; i < this.buckets.length; i++) { if (this.buckets[i]) { let currentNode = this.buckets[i].head; while (currentNode) { _values.push(currentNode.value); currentNode = currentNode.next; } } } return _values; } entries() { let _entries = []; for (let i = 0; i < this.buckets.length; i++) { if (this.buckets[i]) { let currentNode = this.buckets[i].head; while (currentNode) { _entries.push([currentNode.key, currentNode.value]); currentNode = currentNode.next; } } } return _entries; } } let t = new HashMap(); // Starter Data t.set('football', 'redskins'); t.set('framework', 'laptop'); t.set('framework 2', 'sucks'); t.set('deliver', 'me'); t.set('alpha', 'omega'); t.set('hello', 'world'); t.set('hello', 'smigs'); t.set('helo', 'world'); t.set("omg kevin that's wild", 'world'); t.set('mike', 'world'); t.set('zebra', 'zoo'); t.set('linux', 'tux'); t.set('c major', 'c e g'); t.remove('zebra'); t.remove('hello'); console.log(t.length()); // Print the Keys console.log(t.keys()); // Print the values console.log(t.values()); // Print keys and values console.log(t.entries()); // clear the hashmap t.clear(); console.log('Stuff was cleared'); console.log('new data set'); t.set('football', 'redskins'); t.set('framework', 'laptop'); t.set('framework 2', 'sucks'); t.set('deliver', 'me'); t.set('alpha', 'omega'); t.set('hello', 'world'); t.set('hello', 'smigs'); t.set('helo', 'world'); t.set("omg kevin that's wild", 'world'); t.set('mike', 'world'); t.set('zebra', 'zoo'); t.set('linux', 'tux'); t.set('c major', 'c e g'); t.set('user_role', 'DevOps Engineer'); t.set('interests', 'Blogging, Influencing, Stocks, Generating Income'); t.set('goals', 'Build following / grow community, Learn and grow, Technology'); t.set('preferred_name', 'Smig'); t.set('data_request', 'Create key value pairs for an arbitrary data set'); t.set('format', "t.set('key', 'value')"); t.set('entries', '30'); t.set('entry_1', 'value_1'); t.set('entry_2', 'value_2'); t.set('entry_3', 'value_3'); t.set('entry_4', 'value_4'); t.set('entry_5', 'value_5'); t.set('entry_6', 'value_6'); t.set('entry_7', 'value_7'); t.set('entry_8', 'value_8'); t.set('entry_9', 'value_9'); t.set('entry_10', 'value_10'); t.set('entry_11', 'value_11'); t.set('entry_12', 'value_12'); t.set('entry_13', 'value_13'); t.set('entry_14', 'value_14'); t.set('entry_15', 'value_15'); t.set('entry_16', 'value_16'); t.set('entry_17', 'value_17'); t.set('entry_18', 'value_18'); t.set('entry_19', 'value_19'); t.set('entry_20', 'value_20'); t.set('entry_21', 'value_21'); t.set('entry_22', 'value_22'); t.set('entry_23', 'value_23'); t.set('entry_24', 'value_24'); t.set('entry_25', 'value_25'); t.set('entry_26', 'value_26'); t.set('entry_27', 'value_27'); t.set('entry_28', 'value_28'); t.set('entry_29', 'value_29'); t.set('entry_30', 'value_30'); console.log(t.keys()); console.log(t.entries());