From b0fa0627c0a73d3ee0bbba05895efdb04accf78b Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Tue, 4 Nov 2025 13:43:28 +0000 Subject: [PATCH 01/17] fixed bug in adress.js --- Sprint-2/debug/address.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..4ddf31650 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,4 +1,8 @@ // Predict and explain first... +// My prediction: the code will show an Error or "undefined", the Object is fine but +// called in a wrong way in the last line. we cant use object[number] to get a value +// withing an Object, that works only with arrays. Instead, we need to write +// the name of the key that we need. // This code should log out the houseNumber from the address object // but it isn't working... @@ -12,4 +16,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address["houseNumber"]}`); From dbbf108f31e80b685545d0b1944ea4142ac74faa Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Tue, 11 Nov 2025 21:54:08 +0000 Subject: [PATCH 02/17] finished author.js and recipe.js exercies --- Sprint-2/debug/author.js | 6 +++--- Sprint-2/debug/recipe.js | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..1156cbfc1 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,4 +1,6 @@ // Predict and explain first... +// Prediction: the code will throw an error +// Explanation: An object can not be used or accessed as an array. // This program attempts to log out all the property values in the object. // But it isn't working. Explain why first and then fix the problem @@ -11,6 +13,4 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); -} + console.log(author); diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..036a2def4 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,15 +1,17 @@ -// Predict and explain first... + // Predict and explain first... + // to separate the ingredients in different lines we need to use the function: join() + // the ingredients is an array not an object, so we can use join() and pass "\n" to put + // new line between every item. -// This program should log out the title, how many it serves and the ingredients. -// Each ingredient should be logged on a new line -// How can you fix it? + // This program should log out the title, how many it serves and the ingredients. + // Each ingredient should be logged on a new line + // How can you fix it? -const recipe = { - title: "bruschetta", - serves: 2, - ingredients: ["olive oil", "tomatoes", "salt", "pepper"], -}; + const recipe = { + title: "bruschetta", + serves: 2, + ingredients: ["olive oil", "tomatoes", "salt", "pepper"], + }; -console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); + console.log(`Title: ${recipe.title} || serves: ${recipe.serves} +ingredients: \n ${recipe.ingredients.join("\n ")}`); From 8520e7a98d722e081caa7e60c9459b84b38456dd Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Tue, 11 Nov 2025 22:26:03 +0000 Subject: [PATCH 03/17] contains.js exercise done --- Sprint-2/implement/contains.js | 5 ++++- Sprint-2/implement/contains.test.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..1bc171d1a 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,6 @@ -function contains() {} +function contains(obj, find) { + if (obj[find]) return true; + return false; +} module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..19838440b 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -2,7 +2,7 @@ const contains = require("./contains.js"); /* Implement a function called contains that checks an object contains a -particular property +particular property E.g. contains({a: 1, b: 2}, 'a') // returns true as the object contains a key of 'a' @@ -16,20 +16,47 @@ as the object doesn't contains a key of 'c' // Given a contains function // When passed an object and a property name // Then it should return true if the object contains the property, false otherwise +test.todo("contains on empty object returns false"); +test("When the object contains the property return true, false otherwise", () => { + expect(contains({a: 1, b: 2, c: 3}, "a")).toBe(true); + expect(contains({a: 1, b: 2, c: 3}, "d")).toBe(false); +}) // Given an empty object // When passed to contains // Then it should return false test.todo("contains on empty object returns false"); +test("if contains on empty object returns false", () => { + expect(contains({}, "a")).toBe(false); + expect(contains({}, "Hello")).toBe(false); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test.todo("if contains on object with existing property returns true"); +test("if contains on object with existing property returns true", () => { + expect(contains({m: 10, s: 20, w: 5}, "s")).toBe(true); + expect(contains({x: 100, y: 200, z: 300}, "z")).toBe(true); + expect(contains({name: "Ahmed", age: 30}, "name")).toBe(true); +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test.todo("if contains on object with non-existent property returns false"); +test("if contains on object with non-existent property returns false", () => { + expect(contains({m: 10, s: 20, w: 5}, "x")).toBe(false); + expect(contains({num1: 100, num2: 200, num3: 300}, "num5")).toBe(false); + expect(contains({name: "Ahmed", age: 30}, "address")).toBe(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +test.todo("if contains with invalid parameters returns false or throws an error"); +test("if contains with invalid parameters returns false or throws an error", () => { + expect(contains(['a','b','c'], "a")).toBe(false); + expect(contains("string", "a")).toBe(false); + expect(contains(12345, "a")).toBe(false); +}); From 11b498e88df2d9754df0760407bca6fb4c4a4395 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Tue, 11 Nov 2025 23:32:16 +0000 Subject: [PATCH 04/17] lookup.js exercise done --- Sprint-2/implement/lookup.js | 13 ++++++++++--- Sprint-2/implement/lookup.test.js | 10 +++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..5a405b135 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,12 @@ -function createLookup() { - // implementation here -} +function createLookup(arrayOfPairs) { + let obj = {}; + + for (let i = 0; i < arrayOfPairs.length; i++) { + const [key, value] = arrayOfPairs[i]; + obj[key] = value; + } + return obj; +}; module.exports = createLookup; +console.log(createLookup([['US', 'USD'], ['CA', 'CAD']])); diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..73bf81150 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,14 @@ const createLookup = require("./lookup.js"); test.todo("creates a country currency code lookup for multiple codes"); +test("creates a country currency code lookup for multiple codes", () => { + expect(createLookup([['US', 'USD'], ['CA', 'CAD'], ['GB', 'GBP'], ['JP', 'JPY']])).toEqual({ + 'US': 'USD', + 'CA': 'CAD', + 'GB': 'GBP', + 'JP': 'JPY' + }); +}); /* @@ -21,7 +29,7 @@ Then - The values are the corresponding currency codes Example -Given: [['US', 'USD'], ['CA', 'CAD']] +Given: [['US', 'USD'], ['CA', 'CAD']] When createLookup(countryCurrencyPairs) is called From 2c5bf85f8ed4e126b88b0b2bbc5795f32b5484e2 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Wed, 12 Nov 2025 00:00:08 +0000 Subject: [PATCH 05/17] tally.js exercise is done --- Sprint-2/implement/lookup.js | 1 - Sprint-2/implement/tally.js | 17 +++++++++++++++-- Sprint-2/implement/tally.test.js | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 5a405b135..609b1acc9 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -9,4 +9,3 @@ function createLookup(arrayOfPairs) { }; module.exports = createLookup; -console.log(createLookup([['US', 'USD'], ['CA', 'CAD']])); diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..4b42ff32f 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,16 @@ -function tally() {} +function tally(arr) { + let obj = {}; + if (!Array.isArray(arr)) { + throw new Error("Input must be an array"); + } -module.exports = tally; + for (let i = 0; i < arr.length; i++) { + if (!obj[arr[i]]) + obj[arr[i]] = 1; + else if (obj[arr[i]]) + obj[arr[i]]++; + } + return obj; +} + +module.exports = tally; \ No newline at end of file diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..3f6f6dda4 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -19,16 +19,38 @@ const tally = require("./tally.js"); // Given a function called tally // When passed an array of items // Then it should return an object containing the count for each unique item +test.todo("when passed an array of items, it returns an object with counts for each unique item"); +test("when passed an array of items, it returns an object with counts for each unique item", () => { + const input = ['a', 'a', 'b', 'c']; + const expectedOutput = { a: 2, b: 1, c: 1 }; + expect(tally(input)).toEqual(expectedOutput); +}); // Given an empty array // When passed to tally // Then it should return an empty object test.todo("tally on an empty array returns an empty object"); +test("tally on an empty array returns an empty object", () => { + const input = []; + const expectedOutput = {}; + expect(tally(input)).toEqual(expectedOutput); +}); // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +test.todo("tally counts each unique item in an array with duplicates"); +test("tally counts each unique item in an array with duplicates", () => { + const input = ['x', 'y', 'x', 'z', 'y', 'x']; + const expectedOutput = { x: 3, y: 2, z: 1 }; + expect(tally(input)).toEqual(expectedOutput); +}); // Given an invalid input like a string // When passed to tally // Then it should throw an error +test.todo("tally throws an error when passed invalid input"); +test("tally throws an error when passed invalid input", () => { + const input = "invalid input"; + expect(() => tally(input)).toThrow("Input must be an array"); +}); From 0f31edd4bcbd1d2c34d2c8d803f5e5b89201ad20 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Wed, 12 Nov 2025 11:35:42 +0000 Subject: [PATCH 06/17] querystring.js exercise done --- Sprint-2/implement/querystring.js | 13 ++++++------- Sprint-2/implement/querystring.test.js | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..6b4500ce3 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,16 +1,15 @@ function parseQueryString(queryString) { const queryParams = {}; - if (queryString.length === 0) { + if (queryString.length === 0) { return queryParams; } - const keyValuePairs = queryString.split("&"); - - for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; - } + let firstPart = queryString.slice(0, queryString.indexOf("=")); + let secondPart = queryString.slice(queryString.indexOf("=") + 1); + queryParams[firstPart] = secondPart; return queryParams; } module.exports = parseQueryString; + +console.log(parseQueryString("equation=x=y+1")); // { equation: 'x' } \ No newline at end of file diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..81861cc3d 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -3,7 +3,7 @@ // Below is one test case for an edge case the implementation doesn't handle well. // Fix the implementation for this test, and try to think of as many other edge cases as possible - write tests and fix those too. -const parseQueryString = require("./querystring.js") +const parseQueryString = require("./querystring.js") test("parses querystring values containing =", () => { expect(parseQueryString("equation=x=y+1")).toEqual({ From 86876d77ac7eaabf45150aede34409dc117332c8 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Wed, 12 Nov 2025 12:12:45 +0000 Subject: [PATCH 07/17] invert.js done and added tests file invert.test.js --- Sprint-2/implement/querystring.js | 2 +- Sprint-2/implement/querystring.test.js | 10 ++++++++++ Sprint-2/interpret/invert.js | 12 +++++++++++- Sprint-2/interpret/invert.test.js | 9 +++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 Sprint-2/interpret/invert.test.js diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 6b4500ce3..811fdc5a3 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -12,4 +12,4 @@ function parseQueryString(queryString) { module.exports = parseQueryString; -console.log(parseQueryString("equation=x=y+1")); // { equation: 'x' } \ No newline at end of file +console.log(parseQueryString("equation=x=y+1")); \ No newline at end of file diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 81861cc3d..ffea4e5cc 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,3 +10,13 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); + +test("parses empty querystring", () => { + expect(parseQueryString("")).toEqual({}); +}); + +test("parses single key-value pair", () => { + expect(parseQueryString("name=John")).toEqual({ + "name": "John", + }); +}); diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..1513034a7 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,30 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; } // a) What is the current return value when invert is called with { a : 1 } +// the current return value is { key: 1 } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// the current return value is { key: 2 } // c) What is the target return value when invert is called with {a : 1, b: 2} +// the target return value should be { '1': 'a', '2': 'b' } // c) What does Object.entries return? Why is it needed in this program? +// it returns an array of a given object in [key, value] pairs. // d) Explain why the current return value is different from the target output +// because in the loop, it always assigns the property 'key' to the value, +// so the final result only contains one property 'key' with the last value assigned in the loop. // e) Fix the implementation of invert (and write tests to prove it's fixed!) +// Code fixed. + +console.log(invert({ a: 1 })); // { '1': 'a' } +module.exports = invert; diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js new file mode 100644 index 000000000..c056cf6ad --- /dev/null +++ b/Sprint-2/interpret/invert.test.js @@ -0,0 +1,9 @@ +test.todo("check if invert function swaps keys and values"); +test("check if invert function swaps keys and values", () => { + const invert = require("./invert"); + + expect(invert({ a: 1 })).toEqual({ '1': 'a' }); + expect(invert({ a: 1, b: 2 })).toEqual({ '1': 'a', '2': 'b' }); + expect(invert({ x: 10, y: 20 })).toEqual({ '10': 'x', '20': 'y' }); + expect(invert({})).toEqual({}); +}); \ No newline at end of file From adfb25ab5fe7cf05df51a074a9568ae2cd363081 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Fri, 14 Nov 2025 10:13:16 +0000 Subject: [PATCH 08/17] basic function code --- Sprint-2/stretch/count-words.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Sprint-2/stretch/count-words.js b/Sprint-2/stretch/count-words.js index 8e85d19d7..4abc7ed88 100644 --- a/Sprint-2/stretch/count-words.js +++ b/Sprint-2/stretch/count-words.js @@ -26,3 +26,22 @@ 3. Order the results to find out which word is the most common in the input */ + +function countWords(string) { + let outputObject = {}; + let splitString = string.split(" "); + for ( let i = 0; i < splitString.length; i++) { + let word = splitString[i].toLowerCase(); + word = word.replace(/[.,!?]/g, ''); + + if (word.length != 0) { + if (!outputObject[word]) + outputObject[word] = 1; + else + outputObject[word]++; + } + //console.log(splitString[i]); + } + return outputObject; +} +console.log(countWords("Hello ah.med how are you Ahmed? are you ok? ha ?")); \ No newline at end of file From 99b563ec6dd2ffb32cd5175a5f36b2b40dd3b6b4 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Fri, 14 Nov 2025 11:37:07 +0000 Subject: [PATCH 09/17] count-words.js done --- Sprint-2/stretch/count-words.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Sprint-2/stretch/count-words.js b/Sprint-2/stretch/count-words.js index 4abc7ed88..4082aad0f 100644 --- a/Sprint-2/stretch/count-words.js +++ b/Sprint-2/stretch/count-words.js @@ -29,6 +29,7 @@ function countWords(string) { let outputObject = {}; + let sortedByCount = []; let splitString = string.split(" "); for ( let i = 0; i < splitString.length; i++) { let word = splitString[i].toLowerCase(); @@ -42,6 +43,16 @@ function countWords(string) { } //console.log(splitString[i]); } - return outputObject; + + sortedByCount = Object.entries(outputObject); + sortedByCount.sort((a, b) => b[1] - a[1]); + sortedByCount.reduce((acc, [key, value]) => { + acc[key] = value; + return acc; + }, {}); + return sortedByCount; } -console.log(countWords("Hello ah.med how are you Ahmed? are you ok? ha ?")); \ No newline at end of file +console.log(countWords("first first first second third second")); +console.log(countWords("first second third first")); +console.log(countWords("first second third third")); +console.log(countWords("first second third third second first")); \ No newline at end of file From fe14e35375ae9f27fb445b350d1b9f41ed2eec48 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 09:54:57 +0000 Subject: [PATCH 10/17] Updated function contains() in contains.js --- Sprint-2/implement/contains.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 1bc171d1a..a7181766a 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,6 +1,7 @@ function contains(obj, find) { - if (obj[find]) return true; + if (obj.hasOwnProperty(find)) return true; return false; } +//console.log(contains({a: 1, b: 2}, 'toString')); module.exports = contains; From a9a3335511c96a6756b3f9d73247efd64d136cd0 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 10:13:17 +0000 Subject: [PATCH 11/17] Updated Contains.js & contains.test.js --- Sprint-2/implement/contains.js | 8 +++++--- Sprint-2/implement/contains.test.js | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index a7181766a..a4dc924eb 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,7 +1,9 @@ function contains(obj, find) { - if (obj.hasOwnProperty(find)) return true; - return false; + + if(typeof obj !== 'object' || !obj || Array.isArray(obj)) { + return false; + } + return obj.hasOwnProperty(find); } -//console.log(contains({a: 1, b: 2}, 'toString')); module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 19838440b..b1c430654 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -56,7 +56,7 @@ test("if contains on object with non-existent property returns false", () => { // Then it should return false or throw an error test.todo("if contains with invalid parameters returns false or throws an error"); test("if contains with invalid parameters returns false or throws an error", () => { - expect(contains(['a','b','c'], "a")).toBe(false); + expect(contains(['a','b','c'], "1")).toBe(false); expect(contains("string", "a")).toBe(false); expect(contains(12345, "a")).toBe(false); }); From ff9852e4ad3ed546ddeeb345440e9eb95f4b81ae Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 10:23:39 +0000 Subject: [PATCH 12/17] Updated querystring.js --- Sprint-2/implement/querystring.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 811fdc5a3..2abb145c6 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,15 +1,17 @@ function parseQueryString(queryString) { const queryParams = {}; - if (queryString.length === 0) { - return queryParams; - } - let firstPart = queryString.slice(0, queryString.indexOf("=")); - let secondPart = queryString.slice(queryString.indexOf("=") + 1); - queryParams[firstPart] = secondPart; + if (!queryString) return queryParams; + + const eqIndex = queryString.indexOf("="); + + let firstPart = decodeURIComponent(queryString.slice(0, eqIndex)); + let secondPart = decodeURIComponent(queryString.slice(eqIndex + 1)); + + queryParams[firstPart] = secondPart; return queryParams; } module.exports = parseQueryString; -console.log(parseQueryString("equation=x=y+1")); \ No newline at end of file +//console.log(parseQueryString("equation=x=y+1")); \ No newline at end of file From 82959aad86197d4f1ca92361c867dcdb37549367 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 11:33:57 +0000 Subject: [PATCH 13/17] Updated tally.js --- Sprint-2/implement/tally.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 4b42ff32f..40c004c8a 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,5 +1,5 @@ function tally(arr) { - let obj = {}; + let obj = Object.create(null); if (!Array.isArray(arr)) { throw new Error("Input must be an array"); } From b8d931b82b852f20e666a5a1a85656274c57a726 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 11:44:34 +0000 Subject: [PATCH 14/17] Updated count-words.js --- Sprint-2/stretch/count-words.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/Sprint-2/stretch/count-words.js b/Sprint-2/stretch/count-words.js index 4082aad0f..4e8294866 100644 --- a/Sprint-2/stretch/count-words.js +++ b/Sprint-2/stretch/count-words.js @@ -28,9 +28,9 @@ */ function countWords(string) { - let outputObject = {}; - let sortedByCount = []; + let outputObject = Object.create(null); let splitString = string.split(" "); + for ( let i = 0; i < splitString.length; i++) { let word = splitString[i].toLowerCase(); word = word.replace(/[.,!?]/g, ''); @@ -41,18 +41,10 @@ function countWords(string) { else outputObject[word]++; } - //console.log(splitString[i]); } - sortedByCount = Object.entries(outputObject); - sortedByCount.sort((a, b) => b[1] - a[1]); - sortedByCount.reduce((acc, [key, value]) => { - acc[key] = value; - return acc; - }, {}); - return sortedByCount; + return outputObject; } -console.log(countWords("first first first second third second")); -console.log(countWords("first second third first")); -console.log(countWords("first second third third")); -console.log(countWords("first second third third second first")); \ No newline at end of file +console.log(countWords("Hello,World! Hello World!")); +console.log(countWords("constructor constructor")); +console.log(countWords(" Hello World ")); \ No newline at end of file From 75f6f0e50cddcab1a027b25ed307468d1c85931a Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 13:07:17 +0000 Subject: [PATCH 15/17] updated author.js --- Sprint-2/debug/author.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 1156cbfc1..419c6b040 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -13,4 +13,6 @@ const author = { alive: true, }; - console.log(author); +for ( const key in author ) { +console.log(author[key]); +} From 8beb27f60b2181dfe054070463d0d30c2d8e0fdc Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 13:34:46 +0000 Subject: [PATCH 16/17] Updated querystring.js and querystring.test.js --- Sprint-2/implement/querystring.js | 24 ++++++++++++++++-------- Sprint-2/implement/querystring.test.js | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 2abb145c6..2d0e478a7 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -2,16 +2,24 @@ function parseQueryString(queryString) { const queryParams = {}; if (!queryString) return queryParams; - const eqIndex = queryString.indexOf("="); + const pairs = queryString.split("&"); + + for (const pair of pairs) { + const eqIndex = pair.indexOf("="); + + let key, value; + if (eqIndex === -1) { + key = decodeURIComponent(pair); + value = ""; + } else { + key = decodeURIComponent(pair.slice(0, eqIndex)); + value = decodeURIComponent(pair.slice(eqIndex + 1)); + } - let firstPart = decodeURIComponent(queryString.slice(0, eqIndex)); - let secondPart = decodeURIComponent(queryString.slice(eqIndex + 1)); - - queryParams[firstPart] = secondPart; + queryParams[key] = value; + } return queryParams; } -module.exports = parseQueryString; - -//console.log(parseQueryString("equation=x=y+1")); \ No newline at end of file +module.exports = parseQueryString; \ No newline at end of file diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index ffea4e5cc..c8710fd0d 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -20,3 +20,21 @@ test("parses single key-value pair", () => { "name": "John", }); }); + +test("parses key with empty value", () => { + expect(parseQueryString("key=")).toEqual({ + "key": "", + }); +}); + +test("parses empty key with value", () => { + expect(parseQueryString("=value")).toEqual({ + "": "value", + }); +}); + +test("parses key without '=' separator", () => { + expect(parseQueryString("key")).toEqual({ + "key": "", + }); +}); \ No newline at end of file From 3033e55a8d870946b72d9a9c00dee036b6fc3ca5 Mon Sep 17 00:00:00 2001 From: Mohammed Abdoon Date: Sat, 22 Nov 2025 14:00:24 +0000 Subject: [PATCH 17/17] tally.js updated --- Sprint-2/implement/tally.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 40c004c8a..56967e691 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -7,7 +7,7 @@ function tally(arr) { for (let i = 0; i < arr.length; i++) { if (!obj[arr[i]]) obj[arr[i]] = 1; - else if (obj[arr[i]]) + else obj[arr[i]]++; } return obj;