|
1 | 1 | // Fix this implementation |
2 | 2 | // Start by running the tests for this function |
3 | | -// If you're in the week-1 directory, you can run npm test -- fix to run the tests in the fix directory |
| 3 | +// If you're in the Sprint-1 directory, you can run `npm test -- fix` to run the tests in the fix directory |
4 | 4 |
|
5 | | -// Old Code: |
6 | | - |
7 | | -// function calculateMedian(list) { |
8 | | -// const middleIndex = Math.floor(list.length / 2); |
9 | | -// const median = list.splice(middleIndex, 1)[0]; |
10 | | -// return median; |
11 | | -// } |
| 5 | +// Hint: Please consider scenarios when 'list' isn't an array, is empty, |
| 6 | +// or contains values that aren't numbers (the function is expected to throw - see the tests). |
12 | 7 |
|
13 | 8 | // Explanation: |
14 | | -// The original implementation has several mistakes: |
15 | | -// 1 - .splice() mutates or changes the original array. We don't want this to happen. |
16 | | -// 2 - We actually don't need .splice() or any other method to find a median. |
17 | | -// 3 - We must sort the array before we search for the median. |
18 | | -// 4 - We should check if the 'list' parameter actually has numbers, otherwise try to filter |
19 | | -// out all non-numeric values and throw an error or return null if there are no numeric values. |
20 | | - |
21 | | - |
22 | | -// Example of a function calculating median and returning null in case no numeric values provided. |
| 9 | +// Check the input first and throw if there is no sensible median to return. |
| 10 | +// Sort a copy so the caller's array is not mutated, then read the middle |
| 11 | +// element, or the average of the two middle elements when the length is even. |
23 | 12 |
|
24 | 13 | function calculateMedian(list) { |
25 | 14 | if (!Array.isArray(list)) { |
26 | | - return null; |
| 15 | + throw new Error("calculateMedian requires an array of numbers"); |
27 | 16 | } |
28 | | - const onlyNumberList = list.filter(item => typeof item === 'number' && !isNaN(item)); |
29 | | - |
30 | | - if (!onlyNumberList.length) { |
31 | | - return null; |
32 | | - } else { |
33 | | - const sortedList = onlyNumberList.sort((current, next) => current - next); |
34 | | - const indexNearMiddleOfArray = Math.floor(sortedList.length / 2); |
35 | | - if (sortedList.length % 2 === 0) { |
36 | | - return (sortedList[indexNearMiddleOfArray - 1] + sortedList[indexNearMiddleOfArray]) / 2; |
37 | | - } else { |
38 | | - return sortedList[indexNearMiddleOfArray]; |
| 17 | + for (const item of list) { |
| 18 | + if (typeof item !== "number") { |
| 19 | + throw new Error("calculateMedian requires an array of numbers"); |
39 | 20 | } |
40 | 21 | } |
| 22 | + if (list.length === 0) { |
| 23 | + throw new Error("calculateMedian requires a non-empty array"); |
| 24 | + } |
| 25 | + |
| 26 | + const sorted = [...list].sort((a, b) => a - b); |
| 27 | + const middleIndex = Math.floor(sorted.length / 2); |
| 28 | + |
| 29 | + if (sorted.length % 2 === 0) { |
| 30 | + return (sorted[middleIndex - 1] + sorted[middleIndex]) / 2; |
| 31 | + } |
| 32 | + return sorted[middleIndex]; |
41 | 33 | } |
42 | 34 |
|
43 | 35 | module.exports = calculateMedian; |
0 commit comments