From 377bfc42dacdba998ae24fc16005f68f10bcfb73 Mon Sep 17 00:00:00 2001 From: Dario-DC <105294544+Dario-DC@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:24:41 +0200 Subject: [PATCH] feat(curriculum): add hash table lab (#56301) --- client/i18n/locales/english/intro.json | 5 +- .../lab-hash-table-class/index.md | 9 + .../_meta/lab-hash-table-class/meta.json | 11 + .../66f1805aac05f00a7028fbcc.md | 221 ++++++++++++++++++ 4 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 client/src/pages/learn/front-end-development/lab-hash-table-class/index.md create mode 100644 curriculum/challenges/_meta/lab-hash-table-class/meta.json create mode 100644 curriculum/challenges/english/25-front-end-development/lab-hash-table-class/66f1805aac05f00a7028fbcc.md diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json index 9a4d7a34ccb..d868192c26e 100644 --- a/client/i18n/locales/english/intro.json +++ b/client/i18n/locales/english/intro.json @@ -2439,7 +2439,10 @@ "For this lab, you will build a linked list class using JavaScript." ] }, - "wraf": { "title": "265", "intro": [] }, + "lab-hash-table-class": { + "title": "Build a Hash Table Class", + "intro": ["For this lab, you will build a hash table using JavaScript."] + }, "muyw": { "title": "266", "intro": [] }, "quiz-javascript-data-structures": { "title": "JavaScript Data Structures Quiz", diff --git a/client/src/pages/learn/front-end-development/lab-hash-table-class/index.md b/client/src/pages/learn/front-end-development/lab-hash-table-class/index.md new file mode 100644 index 00000000000..090ece74199 --- /dev/null +++ b/client/src/pages/learn/front-end-development/lab-hash-table-class/index.md @@ -0,0 +1,9 @@ +--- +title: Introduction to the Build a Hash Table Class +block: lab-hash-table-class +superBlock: front-end-development +--- + +## Introduction to the Build a Hash Table Class + +For this lab, you will build a hash table using JavaScript. diff --git a/curriculum/challenges/_meta/lab-hash-table-class/meta.json b/curriculum/challenges/_meta/lab-hash-table-class/meta.json new file mode 100644 index 00000000000..2b980d3095f --- /dev/null +++ b/curriculum/challenges/_meta/lab-hash-table-class/meta.json @@ -0,0 +1,11 @@ +{ + "name": "Build a Hash Table Class", + "isUpcomingChange": true, + "usesMultifileEditor": true, + "blockType": "lab", + "dashedName": "lab-hash-table-class", + "order": 265, + "superBlock": "front-end-development", + "challengeOrder": [{ "id": "66f1805aac05f00a7028fbcc", "title": "Build a Hash Table Class" }], + "helpCategory": "JavaScript" +} diff --git a/curriculum/challenges/english/25-front-end-development/lab-hash-table-class/66f1805aac05f00a7028fbcc.md b/curriculum/challenges/english/25-front-end-development/lab-hash-table-class/66f1805aac05f00a7028fbcc.md new file mode 100644 index 00000000000..40b14eea1fe --- /dev/null +++ b/curriculum/challenges/english/25-front-end-development/lab-hash-table-class/66f1805aac05f00a7028fbcc.md @@ -0,0 +1,221 @@ +--- +id: 66f1805aac05f00a7028fbcc +title: Build a Hash Table Class +challengeType: 14 +dashedName: build-a-hash-table-class +--- + +# --description-- + +**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab. + +**User Stories:** + +1. You should define a class named `HashTable` with a `collection` property initialized as an empty object inside its `constructor` method. The `collection` object should store key-value pairs based on the hashed value of the key. +1. The `HashTable` class should have four instance methods, namely `hash`, `add`, `remove`, and `lookup`. +1. The `hash` method should take a string as a parameter and return the hashed value computed as the sum of the UTF-16 code unit of each character in the string. Use the `charCodeAt` method for that. +1. The `add` method should take a key-value pair as the parameters, and hash the key. The hashed value should be used to store the key-value pair inside the hash table (`collection` object). When the same hash value is produced by multiple different keys, each key-value pair should be stored using the same hash value. +1. The `remove` method should take a key as a parameter and remove the corresponding key-value pair from the hash table. If that's the last key-value pair, it should remove the hash key as well. +1. The `lookup` method should take a key as a parameter and return the corresponding value stored inside the hash table, or `null` if not present. + +# --hints-- + +You should have a `HashTable` class. + +```js +assert.isFunction(HashTable); +assert.isObject(new HashTable()); +``` + +Your `HashTable` class should have a `collection` property initialized as an empty object. + +```js +const table = new HashTable(); +assert.isObject(table.collection); +assert.isEmpty(table.collection); +``` + +Your `HashTable` class should have a `hash` method. + +```js +const table = new HashTable(); +assert.isFunction(table.hash); +``` + +`new HashTable().hash("freeCodeCamp")` should return `1182`. + +```js +const table = new HashTable(); +assert.strictEqual(table.hash("freeCodeCamp"), 1182); +``` + +The `hash` method should take a string as a parameter and return the hashed value computed as the sum of the UTF-16 code unit of each character in the string using the `charCodeAt` method. + +```js +const table = new HashTable(); +assert.strictEqual(table.hash("Hey you"), 675); +``` + +Your `HashTable` class should have an `add` method. + +```js +const table = new HashTable(); +assert.isFunction(table.add); +``` + +After calling `hashTable.add("FCC", "freeCodeCamp")`, `hashTable.collection` should become `{ 204: { FCC: 'freeCodeCamp' } }`. + +```js +const table = new HashTable(); +table.add("FCC", "freeCodeCamp"); +assert.deepEqual(table.collection, { 204: { FCC: 'freeCodeCamp' } }); +``` + +The `add` method should take a key-value pair as the parameters, hash the key and store the key-value pair inside the hashed key of the `collection` object. + +```js +const table = new HashTable(); +table.add("test", "this is a test"); +assert.deepEqual(table.collection, { 448: { test: 'this is a test' } }); +``` + +After calling `hashTable.add("FCC", "freeCodeCamp")` and `hashTable.add("CFC", "chloroflourocarbon")`, `hashTable.collection` should become `{ 204: { FCC: 'freeCodeCamp', CFC: 'chloroflourocarbon' } }`. + +```js +const table = new HashTable(); +table.add("FCC", "freeCodeCamp"); +table.add("CFC", "chloroflourocarbon"); +assert.deepEqual(table.collection, { 204: { FCC: 'freeCodeCamp', CFC: 'chloroflourocarbon' } }); +``` + +When the same hash value is produced by multiple different keys, the `add` method should store each key-value pair using the same hash value. + +```js +const table = new HashTable(); +table.add("pan", "frying"); +table.add("nap", "sleeping"); +assert.deepEqual(table.collection, { 319: { pan: 'frying', nap: 'sleeping' } }); +``` + +Your `HashTable` class should have a `remove` method. + +```js +const table = new HashTable(); +assert.isFunction(table.remove); +``` + +When `hashtable.collection` is equal to `{ 204: { FCC: 'freeCodeCamp' } }`, `hashTable.remove("FCC")` should remove both the `FCC` key and the `204` key from the `collection` object. + +```js +const table = new HashTable(); +table.add("FCC", "freeCodeCamp"); +table.remove("FCC"); +assert.isEmpty(table.collection); +``` + +When `hashtable.collection` is equal to `{ 204: { FCC: 'freeCodeCamp', CFC: 'chloroflourocarbon' } }`, `hashTable.remove("FCC")` should only remove the `FCC` key from the value of the key `204`. + +```js +const table = new HashTable(); +table.add("FCC", "freeCodeCamp"); +table.add("CFC", "chloroflourocarbon"); +table.remove("FCC"); +assert.deepEqual(table.collection, { 204: { CFC: 'chloroflourocarbon' } }); +``` + +The `remove` method should accept a key as input and remove both the associated key value pair and the hash key when it is empty. + +```js +const table = new HashTable(); +table.add("FCC", "freeCodeCamp"); +table.remove("FCC"); +assert.isEmpty(table.collection); +``` + +The `remove` method should only remove the correct key value pair from the hash key object. + +```js +const table = new HashTable(); +table.add("pan", "frying"); +table.add("nap", "sleeping"); +table.remove("pan"); +assert.deepEqual(table.collection, { 319: { nap: 'sleeping' } }); +``` + +Your `HashTable` class should have a `lookup` method. + +```js +const table = new HashTable(); +assert.isFunction(table.lookup); +``` + +`hashTable.lookup("FCC")` should return the value of the `FCC` key stored within `hashtable.collection`. + +```js +const table = new HashTable(); +table.add("FCC", "freeCodeCamp"); +table.add("CFC", "chloroflourocarbon"); +assert.strictEqual(table.lookup("FCC"), "freeCodeCamp"); +``` + +`hashTable.lookup("FCC")` should return `null` if there's no `FCC` key stored within `hashtable.collection`. + +```js +const table = new HashTable(); +table.add("FCC", "freeCodeCamp"); +table.add("CFC", "chloroflourocarbon"); +assert.isNull(table.lookup("x")); +``` + +# --seed-- + +## --seed-contents-- + +```js + +``` + +# --solutions-- + +```js +class HashTable { + constructor() { + this.collection = {}; + } + + hash(string) { + let hashed = 0; + for (let i = 0; i < string.length; i++) { + hashed += string.charCodeAt(i); + } + return hashed + } + + add(key, val) { + const theHash = this.hash(key); + if (!this.collection.hasOwnProperty(theHash)) { + this.collection[theHash] = {}; + } + this.collection[theHash][key] = val; + } + + remove(key) { + const theHash = this.hash(key); + const hashedObj = this.collection[theHash]; + if (hashedObj.hasOwnProperty(key)) { + delete hashedObj[key]; + } + if (!Object.keys(hashedObj).length) { + delete this.collection[theHash]; + } + } + + lookup(key) { + const theHash = this.hash(key); + if (this.collection.hasOwnProperty(theHash)) { + return this.collection[theHash][key]; + } + return null + } +} +```