From 4718073cb83320af8fbb4c2f77d58d192a8932a2 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Wed, 10 Jan 2018 14:21:28 +0100 Subject: [PATCH] feat(median): Add module median Get the median from a list of numbers --- src/__tests__/median.js | 26 ++++++++++++++++++++++++++ src/index.js | 4 ++++ src/median.js | 24 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 src/__tests__/median.js create mode 100644 src/median.js diff --git a/src/__tests__/median.js b/src/__tests__/median.js new file mode 100644 index 0000000..cb2875a --- /dev/null +++ b/src/__tests__/median.js @@ -0,0 +1,26 @@ +import median from '../median'; + +describe('Core.median', () => { + test('returns middle value of an odd-length list', () => { + expect(median([2, 9, 7])).toBe(7); + expect(median([3, 2, 11, 7, 9])).toBe(7); + expect(median([2])).toBe(2); + }); + + test('returns mean of two middle values of a nonempty even-length list', () => { + expect(median([7, 2])).toBe(4.5); + expect(median([7, 2, 10, 9])).toBe(8); + }); + + test('returns NaN for an empty list', () => { + expect(median([])).toBe(NaN); + }); + + test('handles array-like object', () => { + function getArgs() { + return arguments; // eslint-disable-line prefer-rest-params + } + + expect(median(getArgs(1, 2, 3))).toBe(2); + }); +}); diff --git a/src/index.js b/src/index.js index ddeef45..2aa465d 100644 --- a/src/index.js +++ b/src/index.js @@ -31,6 +31,8 @@ import keys from './keys'; import last from './last'; import length from './length'; import map from './map'; +import mean from './mean'; +import median from './median'; import modulo from './modulo'; import multiply from './multiply'; import negate from './negate'; @@ -84,6 +86,8 @@ export { last, length, map, + mean, + median, modulo, multiply, negate, diff --git a/src/median.js b/src/median.js new file mode 100644 index 0000000..f02f02c --- /dev/null +++ b/src/median.js @@ -0,0 +1,24 @@ +import length from './length'; +import divide from './divide'; +import modulo from './modulo'; +import nth from './nth'; +import slice from './slice'; +import mean from './mean'; + +const median = list => { + const sorted = Array.prototype.sort.call(list, (a, b) => { + if (a > b) return 1; + if (a < b) return -1; + return 0; + }); + + const l = length(sorted); + const half = divide(l, 2); + + if (modulo(l, 2) > 0) return nth(Math.floor(half), sorted); + + const sub = slice(half - 1, half + 1, sorted); + return mean(sub); +}; + +export { median as default };