Skip to content

Commit 268ee04

Browse files
Complete Sprint-1: Fix median, Implement max/sum/dedupe, and Refactor includes
1 parent 96d077b commit 268ee04

8 files changed

Lines changed: 144 additions & 50 deletions

File tree

Sprint-1/fix/median.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,35 @@
66
// or 'list' has mixed values (the function is expected to sort only numbers).
77

88
function calculateMedian(list) {
9-
const middleIndex = Math.floor(list.length / 2);
10-
const median = list.splice(middleIndex, 1)[0];
11-
return median;
9+
// 1. Guard clause: Check if the input is an array
10+
if (!Array.isArray(list)) {
11+
return null;
12+
}
13+
14+
// 2. Filter the array to keep only numbers
15+
const numbersOnly = list.filter(
16+
(item) => typeof item === "number" && !isNaN(item)
17+
);
18+
19+
// 3. Check for an empty array
20+
if (numbersOnly.length === 0) {
21+
return null;
22+
}
23+
24+
// 4. Sort the numbers in ascending order
25+
numbersOnly.sort((a, b) => a - b);
26+
27+
// 5. Calculate the middle index
28+
const middleIndex = Math.floor(numbersOnly.length / 2);
29+
30+
// 6. Check if the length is even or odd
31+
if (numbersOnly.length % 2 === 0) {
32+
// The length is EVEN
33+
return (numbersOnly[middleIndex - 1] + numbersOnly[middleIndex]) / 2;
34+
} else {
35+
// The length is ODD
36+
return numbersOnly[middleIndex];
37+
}
1238
}
1339

1440
module.exports = calculateMedian;

Sprint-1/implement/dedupe.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
function dedupe() {}
1+
// dedupe.js
2+
// Remove duplicate values from an array, preserving the first occurrence of each element
3+
4+
function dedupe(arr) {
5+
// Return empty array if input is empty
6+
7+
// Use Set to automatically remove duplicates, then spread back into an array
8+
// Set keeps only unique values in insertion order
9+
return [...new Set(arr)];
10+
}
11+
12+
module.exports = dedupe;

Sprint-1/implement/dedupe.test.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,36 @@
11
const dedupe = require("./dedupe.js");
2-
/*
3-
Dedupe Array
4-
5-
📖 Dedupe means **deduplicate**
6-
7-
In this kata, you will need to deduplicate the elements of an array
8-
9-
E.g. dedupe(['a','a','a','b','b','c']) target output: ['a','b','c']
10-
E.g. dedupe([5, 1, 1, 2, 3, 2, 5, 8]) target output: [5, 1, 2, 3, 8]
11-
E.g. dedupe([1, 2, 1]) target output: [1, 2]
12-
*/
13-
14-
// Acceptance Criteria:
152

163
// Given an empty array
174
// When passed to the dedupe function
185
// Then it should return an empty array
19-
test.todo("given an empty array, it returns an empty array");
6+
test("given an empty array, it returns an empty array", () => {
7+
expect(dedupe([])).toEqual([]);
8+
});
209

2110
// Given an array with no duplicates
2211
// When passed to the dedupe function
2312
// Then it should return a copy of the original array
13+
test("given an array with no duplicates, returns a copy of the array", () => {
14+
expect(dedupe([1, 2, 3])).toEqual([1, 2, 3]);
15+
});
16+
17+
// Given an array with duplicate strings
18+
// When passed to the dedupe function
19+
// Then it should remove duplicates, preserving first occurrence
20+
test("removes duplicate strings", () => {
21+
expect(dedupe(["a", "a", "a", "b", "b", "c"])).toEqual(["a", "b", "c"]);
22+
});
23+
24+
// Given an array with duplicate numbers
25+
// When passed to the dedupe function
26+
// Then it should remove duplicates, preserving first occurrence
27+
test("removes duplicate numbers", () => {
28+
expect(dedupe([5, 1, 1, 2, 3, 2, 5, 8])).toEqual([5, 1, 2, 3, 8]);
29+
});
2430

25-
// Given an array with strings or numbers
31+
// Given an array with mixed duplicates
2632
// When passed to the dedupe function
27-
// Then it should remove the duplicate values, preserving the first occurence of each element
33+
// Then it should remove duplicates preserving first occurrence
34+
test("removes duplicates in mixed array", () => {
35+
expect(dedupe([1, 2, 1])).toEqual([1, 2]);
36+
});

Sprint-1/implement/max.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1+
// max.js
2+
// Find the largest numerical element in an array
3+
// Non-numeric values are ignored
4+
15
function findMax(elements) {
6+
// Filter to keep only numbers (ignores strings, null, undefined, etc.)
7+
const numbersOnly = elements.filter(
8+
(item) => typeof item === "number" && !isNaN(item)
9+
);
10+
11+
// If no numbers remain, return -Infinity (consistent with Math.max() behaviour)
12+
if (numbersOnly.length === 0) return -Infinity;
13+
14+
// Math.max with spread returns the largest number
15+
return Math.max(...numbersOnly);
216
}
317

418
module.exports = findMax;

Sprint-1/implement/max.test.js

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,50 @@
1-
/* Find the maximum element of an array of numbers
2-
3-
In this kata, you will need to implement a function that find the largest numerical element of an array.
4-
5-
E.g. max([30, 50, 10, 40]), target output: 50
6-
E.g. max(['hey', 10, 'hi', 60, 10]), target output: 60 (sum ignores any non-numerical elements)
7-
8-
You should implement this function in max.js, and add tests for it in this file.
9-
10-
We have set things up already so that this file can see your function from the other file.
11-
*/
12-
131
const findMax = require("./max.js");
142

153
// Given an empty array
164
// When passed to the max function
175
// Then it should return -Infinity
18-
// Delete this test.todo and replace it with a test.
19-
test.todo("given an empty array, returns -Infinity");
6+
test("given an empty array, returns -Infinity", () => {
7+
expect(findMax([])).toBe(-Infinity);
8+
});
209

2110
// Given an array with one number
2211
// When passed to the max function
2312
// Then it should return that number
13+
test("given an array with one number, returns that number", () => {
14+
expect(findMax([42])).toBe(42);
15+
});
2416

2517
// Given an array with both positive and negative numbers
2618
// When passed to the max function
2719
// Then it should return the largest number overall
20+
test("returns the largest number from positive and negative values", () => {
21+
expect(findMax([-10, -3, 0, 5, 2])).toBe(5);
22+
});
2823

2924
// Given an array with just negative numbers
3025
// When passed to the max function
3126
// Then it should return the closest one to zero
27+
test("returns the closest to zero when all numbers are negative", () => {
28+
expect(findMax([-5, -1, -3])).toBe(-1);
29+
});
3230

3331
// Given an array with decimal numbers
3432
// When passed to the max function
3533
// Then it should return the largest decimal number
34+
test("returns the largest decimal number", () => {
35+
expect(findMax([1.1, 2.5, 0.9, 2.4])).toBe(2.5);
36+
});
3637

3738
// Given an array with non-number values
3839
// When passed to the max function
3940
// Then it should return the max and ignore non-numeric values
41+
test("ignores non-numeric values and returns the max number", () => {
42+
expect(findMax(["hey", 10, "hi", 60, 10])).toBe(60);
43+
});
4044

4145
// Given an array with only non-number values
4246
// When passed to the max function
43-
// Then it should return the least surprising value given how it behaves for all other inputs
47+
// Then it should return -Infinity (same as empty array behaviour)
48+
test("returns -Infinity when array contains only non-numeric values", () => {
49+
expect(findMax(["a", "b", null])).toBe(-Infinity);
50+
});

Sprint-1/implement/sum.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1+
// sum.js
2+
// Sum all numerical elements in an array
3+
// Non-numeric values are ignored
4+
15
function sum(elements) {
6+
// Filter to keep only numbers (ignores strings, null, undefined, etc.)
7+
const numbersOnly = elements.filter(
8+
(item) => typeof item === "number" && !isNaN(item)
9+
);
10+
11+
// If no numbers found, return 0 (consistent with empty array behaviour)
12+
if (numbersOnly.length === 0) return 0;
13+
14+
// reduce() accumulates all numbers into a single total
15+
// 0 is the initial value of the accumulator
16+
return numbersOnly.reduce((total, num) => total + num, 0);
217
}
318

419
module.exports = sum;

Sprint-1/implement/sum.test.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,43 @@
1-
/* Sum the numbers in an array
2-
3-
In this kata, you will need to implement a function that sums the numerical elements of an array
4-
5-
E.g. sum([10, 20, 30]), target output: 60
6-
E.g. sum(['hey', 10, 'hi', 60, 10]), target output: 80 (ignore any non-numerical elements)
7-
*/
8-
91
const sum = require("./sum.js");
102

11-
// Acceptance Criteria:
12-
133
// Given an empty array
144
// When passed to the sum function
155
// Then it should return 0
16-
test.todo("given an empty array, returns 0")
6+
test("given an empty array, returns 0", () => {
7+
expect(sum([])).toBe(0);
8+
});
179

1810
// Given an array with just one number
1911
// When passed to the sum function
2012
// Then it should return that number
13+
test("given an array with one number, returns that number", () => {
14+
expect(sum([5])).toBe(5);
15+
});
2116

2217
// Given an array containing negative numbers
2318
// When passed to the sum function
2419
// Then it should still return the correct total sum
20+
test("correctly sums arrays containing negative numbers", () => {
21+
expect(sum([10, -3, 5])).toBe(12);
22+
});
2523

2624
// Given an array with decimal/float numbers
2725
// When passed to the sum function
2826
// Then it should return the correct total sum
27+
test("correctly sums decimal numbers", () => {
28+
expect(sum([1.5, 2.5, 3.0])).toBe(7);
29+
});
2930

3031
// Given an array containing non-number values
3132
// When passed to the sum function
3233
// Then it should ignore the non-numerical values and return the sum of the numerical elements
34+
test("ignores non-numeric values and sums only numbers", () => {
35+
expect(sum(["hey", 10, "hi", 60, 10])).toBe(80);
36+
});
3337

3438
// Given an array with only non-number values
3539
// When passed to the sum function
36-
// Then it should return the least surprising value given how it behaves for all other inputs
40+
// Then it should return 0 (same as empty array behaviour)
41+
test("returns 0 when array contains only non-numeric values", () => {
42+
expect(sum(["a", null, undefined])).toBe(0);
43+
});

Sprint-1/refactor/includes.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
// Refactor the implementation of includes to use a for...of loop
1+
// includes.js
2+
// Refactored to use for...of loop instead of a traditional for loop
3+
// Behaviour is identical — only the loop style changed
24

35
function includes(list, target) {
4-
for (let index = 0; index < list.length; index++) {
5-
const element = list[index];
6+
// for...of iterates directly over each element value
7+
// No need to manage an index variable manually
8+
for (const element of list) {
9+
// If the current element matches the target, return true immediately
610
if (element === target) {
711
return true;
812
}
913
}
14+
// If no element matched after the full loop, return false
1015
return false;
1116
}
1217

0 commit comments

Comments
 (0)