-
-
Notifications
You must be signed in to change notification settings - Fork 286
Sheffield | 26-ITP-Jan | Mahmoud Shaabo | Sprint 2 | Module-Data-Groups #1069
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
303455f
2d34473
51c11d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,12 @@ | ||
| function contains() {} | ||
| // Check if an object contains a specific property | ||
| function contains(object, propertyName) { | ||
| // If the input is not a valid object or is an array, return false | ||
| if (typeof object !== "object" || object === null || Array.isArray(object)) { | ||
| return false; | ||
| } | ||
|
|
||
| // Use hasOwnProperty to check if the key exists in the object | ||
| return object.hasOwnProperty(propertyName); | ||
| } | ||
|
|
||
| module.exports = contains; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,16 +20,27 @@ as the object doesn't contains a key of 'c' | |
| // Given an empty object | ||
| // When passed to contains | ||
| // Then it should return false | ||
| test.todo("contains on empty object returns false"); | ||
| test("contains on empty object returns false", () => { | ||
| expect(contains({}, "a")).toBe(false); | ||
| }); | ||
|
|
||
| // Given an object with properties | ||
| // When passed to contains with an existing property name | ||
| // Then it should return true | ||
| test("contains returns true for an existing property", () => { | ||
| expect(contains({ a: 1, b: 2 }, "a")).toBe(true); | ||
| }); | ||
|
|
||
| // Given an object with properties | ||
| // When passed to contains with a non-existent property name | ||
| // Then it should return false | ||
| test("contains returns false for a non-existent property", () => { | ||
| expect(contains({ a: 1, b: 2 }, "c")).toBe(false); | ||
| }); | ||
|
|
||
| // Given invalid parameters like an array | ||
| // When passed to contains | ||
| // Then it should return false or throw an error | ||
| test("contains returns false when passed an array instead of an object", () => { | ||
| expect(contains(["a", "b"], "0")).toBe(false); | ||
| }); | ||
|
Comment on lines
+44
to
+46
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test does not yet confirm that the function correctly returns false when the first argument is an array. Arrays are objects, with their indices acting as keys. A proper test should use a valid |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,16 @@ | ||
| function createLookup() { | ||
| // implementation here | ||
| // Take an array of pairs and return a lookup object | ||
| function createLookup(pairs) { | ||
| // Create an empty object to store the results | ||
| const lookup = {}; | ||
|
|
||
| // Loop through each pair in the array | ||
| for (const pair of pairs) { | ||
| // pair[0] is the key (country code), pair[1] is the value (currency code) | ||
| lookup[pair[0]] = pair[1]; | ||
| } | ||
|
|
||
| // Return the completed lookup object | ||
| return lookup; | ||
| } | ||
|
|
||
| module.exports = createLookup; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,35 @@ | ||
| // Parse a query string into an object of key-value pairs | ||
| function parseQueryString(queryString) { | ||
| // Create an empty object to store the results | ||
| const queryParams = {}; | ||
|
|
||
| // If the input is empty, return the empty object | ||
| if (queryString.length === 0) { | ||
| return queryParams; | ||
| } | ||
|
|
||
| // Split the string by "&" to get each key=value pair | ||
| const keyValuePairs = queryString.split("&"); | ||
|
|
||
| for (const pair of keyValuePairs) { | ||
| const [key, value] = pair.split("="); | ||
| queryParams[key] = value; | ||
| // Skip empty pairs caused by double ampersands like "key1=value1&&key2=value2" | ||
| if (pair === "") { | ||
| continue; | ||
| } | ||
|
|
||
| // Find the position of the FIRST "=" only | ||
| const firstEqualIndex = pair.indexOf("="); | ||
|
|
||
| // If there is no "=", the whole pair is the key with an empty value | ||
| if (firstEqualIndex === -1) { | ||
| queryParams[pair] = ""; | ||
| } else { | ||
| // Everything before the first "=" is the key | ||
| const key = pair.slice(0, firstEqualIndex); | ||
| // Everything after the first "=" is the value (may contain more "=" signs) | ||
| const value = pair.slice(firstEqualIndex + 1); | ||
| queryParams[key] = value; | ||
| } | ||
|
Comment on lines
+20
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does your function return the value you expect from the following function call?
|
||
| } | ||
|
|
||
| return queryParams; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,22 @@ | ||
| function tally() {} | ||
| // Count the frequency of each item in an array | ||
| function tally(items) { | ||
| // If the input is not an array, throw an error | ||
| if (!Array.isArray(items)) { | ||
| throw new Error("Input must be an array"); | ||
| } | ||
|
|
||
| // Create an empty object to store the counts | ||
| const counts = Object.create(null); | ||
|
|
||
| // Loop through each item in the array | ||
| for (const item of items) { | ||
| // If this item already exists in counts, add 1 to it | ||
| // If it does not exist yet, start at 1 | ||
| counts[item] = (counts[item] || 0) + 1; | ||
| } | ||
|
|
||
| // Return the object with all the counts | ||
| return counts; | ||
| } | ||
|
|
||
| module.exports = tally; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,45 @@ | ||
| // Let's define how invert should work | ||
|
|
||
| // Given an object | ||
| // When invert is passed this object | ||
| // Then it should swap the keys and values in the object | ||
|
|
||
| // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} | ||
| // E.g. invert({x: 10, y: 20}), target output: {"10": "x", "20": "y"} | ||
|
|
||
| /* | ||
| --- Answers to the Interpret Questions --- | ||
|
|
||
| a) What is the return value of invert({a: 1}) in the old broken code? | ||
| Answer: It returned { key: 1 } because dot notation (.key) creates a literal string key named "key". | ||
|
|
||
| b) What is the return value of invert({a: 1, b: 2}) in the old broken code? | ||
| Answer: It returned { key: 2 } because the literal property "key" is overwritten in the second loop iteration. | ||
|
|
||
| c) What is the target return value of invert({a: 1, b: 2})? | ||
| Answer: The target return value is { "1": "a", "2": "b" }. | ||
|
|
||
| c-continued) What does Object.entries do? Why is it needed here? | ||
| Answer: Object.entries(obj) converts the object into an array of key-value pairs, like [["a", 1], ["b", 2]]. It is needed because we cannot use a 'for...of' loop directly on a standard object. | ||
|
|
||
| d) Why is the current return value different from the target? | ||
| Answer: Because the old code used invertedObj.key (a hardcoded key name) instead of assigning the dynamic value as the new key. | ||
|
|
||
| e) How can you fix it? | ||
| Answer: By using bracket notation to set the 'value' as the new dynamic key, and assigning the 'key' as its value: invertedObj[value] = key; | ||
| */ | ||
|
|
||
| // Swap keys and values in an object | ||
| function invert(obj) { | ||
| // Create an empty object to store the swapped pairs | ||
| const invertedObj = {}; | ||
|
|
||
| // Loop through each [key, value] pair in the original object | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| invertedObj.key = value; | ||
| // Use the VALUE as the new key, and the KEY as the new value | ||
| invertedObj[value] = key; | ||
| } | ||
|
|
||
| // Return the inverted object | ||
| return invertedObj; | ||
| } | ||
|
|
||
| // a) What is the current return value when invert is called with { a : 1 } | ||
|
|
||
| // b) What is the current return value when invert is called with { a: 1, b: 2 } | ||
|
|
||
| // c) What is the target return value when invert is called with {a : 1, b: 2} | ||
|
|
||
| // c) What does Object.entries return? Why is it needed in this program? | ||
|
|
||
| // d) Explain why the current return value is different from the target output | ||
|
|
||
| // e) Fix the implementation of invert (and write tests to prove it's fixed!) | ||
| module.exports = invert; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your code works.
Here is an alternative worth exploring:
Since ingredient values are separated by '\n' in the output, we could also use
Array.prototype.join()to construct the equivalent string and then output the resulting string.