forked from freeCodeCamp/freeCodeCamp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(curriculum): add hash table lab (freeCodeCamp#56301)
- Loading branch information
Showing
4 changed files
with
245 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
client/src/pages/learn/front-end-development/lab-hash-table-class/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
11 changes: 11 additions & 0 deletions
11
curriculum/challenges/_meta/lab-hash-table-class/meta.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} |
221 changes: 221 additions & 0 deletions
221
...glish/25-front-end-development/lab-hash-table-class/66f1805aac05f00a7028fbcc.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} | ||
``` |