diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index b22590bc6..6ec3f356d 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -6,9 +6,44 @@ // or 'list' has mixed values (the function is expected to sort only numbers). function calculateMedian(list) { - const middleIndex = Math.floor(list.length / 2); - const median = list.splice(middleIndex, 1)[0]; - return median; + // If input is not an array + if (Array.isArray(list) === false) { + return null; + } + + // Declare empty array so input array is not modified. + const sortedList = []; + + // Populate sortedList with valid numbers. Numbers in string format is not processed. + for (let i = 0; i < list.length; i++) { + if (typeof list[i] === "number" && !isNaN(list[i])) { + sortedList.push(list[i]); + } + // else if to processes numbers in strings. + /* + else if (typeof list[i] === 'string' && !isNaN(Number(list[i]))) { + sortedList.push(Number(list[i])); + } */ + } + + // Throw error if list is empty or has no numbers + if (sortedList.length === 0) { + //throw new Error('null'); + return null; + } + + // Sort the array numerically + sortedList.sort((a, b) => a - b); + + const mid = Math.floor(sortedList.length / 2); + + // If length is odd, return middle element + if (sortedList.length % 2 !== 0) { + return sortedList[mid]; + } + + // If length is even, return average of two middle elements + return (sortedList[mid - 1] + sortedList[mid]) / 2; } module.exports = calculateMedian; diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 781e8718a..265e68e58 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1 +1,14 @@ -function dedupe() {} +function dedupe(arr) { + // Create a Set to get unique values + const uniqueSet = new Set(arr); + + // Clear the input array + arr.length = 0; + + // Repopulate the input array with unique values + arr.push(...uniqueSet); + + return arr; +} + +module.exports = dedupe; diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 23e0f8638..166b43f8f 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -16,12 +16,37 @@ E.g. dedupe([1, 2, 1]) target output: [1, 2] // Given an empty array // When passed to the dedupe function // Then it should return an empty array -test.todo("given an empty array, it returns an empty array"); +// test.todo("given an empty array, it returns an empty array"); // Given an array with no duplicates // When passed to the dedupe function // Then it should return a copy of the original array +describe("dedupe", () => { + it("given an empty array, it returns an empty array", () => { + const list = []; + expect(dedupe(list)).toEqual([]); + }); + [ + { input: [1, 2, 3], expected: [1, 2, 3] }, + { input: [5, 4, 3, 2, 1], expected: [5, 4, 3, 2, 1] }, + { input: [2, 1, 4, 3], expected: [2, 1, 4, 3] }, + { input: ["a", "2", "c", 4, "b", 6], expected: ["a", "2", "c", 4, "b", 6] }, + ].forEach(({ input, expected }) => + it(`returns a same copy for [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) + ); + + [ + { input: ["a", "a", "a", "b", "b", "c"], expected: ["a", "b", "c"] }, + { input: [5, 1, 1, 2, 3, 2, 5, 8], expected: [5, 1, 2, 3, 8] }, + { input: [1, 2, 1], expected: [1, 2] }, + { input: ["a", 4, "c", 4, "c", 6], expected: ["a", 4, "c", 6] }, + ].forEach(({ input, expected }) => + it(`returns a de-duplicated copy for [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) + ); +}); // Given an array with strings or numbers // When passed to the dedupe function -// Then it should remove the duplicate values, preserving the first occurence of each element +// Then it should remove the duplicate values, preserving the first occurrence of each element diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 6dd76378e..c65311f7a 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,15 @@ -function findMax(elements) { +function findMax(arr) { + let maxNum = -Infinity; + + for (let item of arr) { + if (typeof item === 'number' && !isNaN(item)) { + if (item > maxNum) { + maxNum = item; + } + } + } + + return maxNum; } module.exports = findMax; diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index 82f18fd88..ab1ae8fc7 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -16,7 +16,6 @@ const findMax = require("./max.js"); // When passed to the max function // Then it should return -Infinity // Delete this test.todo and replace it with a test. -test.todo("given an empty array, returns -Infinity"); // Given an array with one number // When passed to the max function @@ -41,3 +40,37 @@ test.todo("given an empty array, returns -Infinity"); // Given an array with only non-number values // When passed to the max function // Then it should return the least surprising value given how it behaves for all other inputs + +describe("findMax function", () => { + test("should return -Infinity for an empty array", () => { + expect(findMax([])).toBe(-Infinity); + }); + + test("should return the number for an array with one number", () => { + expect(findMax([42])).toBe(42); + expect(findMax([5])).toBe(5); + }); + + test("should return the largest number for array with positive and negative numbers", () => { + expect(findMax([30, -50, 10, 40, -20])).toBe(40); + expect(findMax([19, 80, -11, 46, 7])).toBe(80); + }); + + test("should return the closest to zero for array with only negative numbers", () => { + expect(findMax([-100, -50, -10, -1, -200])).toBe(-1); + expect(findMax([-100, -50, -10, -999, -200])).toBe(-10); + }); + + test("should return the largest decimal number", () => { + expect(findMax([1.5, 2.7, 0.3, 1.9])).toBe(2.7); + expect(findMax([0.1, 1.2, 66.3, 7.4])).toBe(66.3); + }); + + test("should ignore non-numeric values and return max number", () => { + expect(findMax(["hey", 10, "hi", 60, 10])).toBe(60); + }); + + test("should return -Infinity for array with only non-number values", () => { + expect(findMax(["hey", "hi", true, null, undefined])).toBe(-Infinity); + }); +}); diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 9062aafe3..64f880d95 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,4 +1,11 @@ -function sum(elements) { +function sum(arr) { + let total = 0; + for (let i = 0; i < arr.length; i++) { + if (typeof arr[i] === 'number' && !isNaN(arr[i])) { + total += arr[i]; + } + } + return total; } module.exports = sum; diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index dd0a090ca..3de3f8b44 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -13,7 +13,6 @@ const sum = require("./sum.js"); // Given an empty array // When passed to the sum function // Then it should return 0 -test.todo("given an empty array, returns 0") // Given an array with just one number // When passed to the sum function @@ -34,3 +33,40 @@ test.todo("given an empty array, returns 0") // Given an array with only non-number values // When passed to the sum function // Then it should return the least surprising value given how it behaves for all other inputs + +describe('sum function', () => { + // Test for empty array + test('should return 0 for an empty array', () => { + expect(sum([])).toEqual(0); + }); + + // Test for array with one number + test('should return the number for an array with one number', () => { + expect(sum([42])).toEqual(42); + }); + + // Test for array with negative numbers + test('should correctly sum negative numbers', () => { + expect(sum([-10, 20, -30])).toBe(-20); + }); + + // Test for array with decimal/float numbers + test('should correctly sum decimal/float numbers', () => { + expect(sum([1.5, 2.7, 3.2])).toBeCloseTo(7.4); // Using toBeCloseTo for floating-point precision + }); + + // Test for array with non-number values + test('should ignore non-number values and sum numerical elements', () => { + expect(sum(['hey', 10, 'hi', 60, 10])).toBe(80); + }); + + // Test for array with only non-number values + test('should return 0 for an array with only non-number values', () => { + expect(sum(['hello', 'world', null, undefined])).toBe(0); + }); + + // Additional test for edge cases + test('should handle mixed types including NaN and invalid numbers', () => { + expect(sum([NaN, 10, undefined, '20', null, 5])).toBe(15); + }); +}); \ No newline at end of file diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 29dad81f0..4017c0eab 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -1,9 +1,8 @@ // Refactor the implementation of includes to use a for...of loop function includes(list, target) { - for (let index = 0; index < list.length; index++) { - const element = list[index]; - if (element === target) { + for (const value of list) { + if (value === target) { return true; } }