From 75c65a15c2321acc7929bc2ea85fc300dd8274c3 Mon Sep 17 00:00:00 2001 From: RuSaG0 Date: Thu, 9 Dec 2021 17:56:55 +0300 Subject: [PATCH 1/4] median --- Maths/AverageMedian.js | 72 ++++++++++++++++++---- Maths/test/AverageMedian.test.js | 100 +++++++++++++++++++++++++------ 2 files changed, 140 insertions(+), 32 deletions(-) diff --git a/Maths/AverageMedian.js b/Maths/AverageMedian.js index 06d9776776..9e49acd2ec 100644 --- a/Maths/AverageMedian.js +++ b/Maths/AverageMedian.js @@ -8,22 +8,68 @@ * else if the length of the array is odd number, the median value will be the middle number in the array */ -const averageMedian = (numbers) => { - let median = 0 - const numLength = numbers.length - numbers = numbers.sort(sortNumbers) - - if (numLength % 2 === 0) { - median = (numbers[numLength / 2 - 1] + numbers[numLength / 2]) / 2 - } else { - median = numbers[(numLength - 1) / 2] +const toArray = (_iterable, _selector) => { + const res = []; + if(!_selector) { + for (const x of _iterable) + res.push(x); } + else { + for (const x of _iterable) + res.push(_selector(x)); + } + return res; +}; - return median -} +const averageMedian = (_arrayOrIterable, {sort, selector} = {}) => { + let array = _arrayOrIterable; + + const isArray = Array.isArray(_arrayOrIterable); + if(!isArray) + array = toArray(array); + + const len = array.length; + if (len <= 0) + return undefined; + if (len === 1) { + if (selector) + return selector(array[0]); + return array[0]; + } + + if (len === 2) { + const a = array[0]; + const b = array[1]; + if (selector) + return 0.5 * (selector(a) + selector(b)); + return 0.5 * (a + b); + } + + let data = array; + if (sort !== false) { + if(isArray) + data = [...array]; + + if (selector) + data.sort((_x, _y) => selector(_x) - selector(_y)); + else + data.sort(); + } + + if (len % 2 === 0) { + const i = len / 2; + const a = data[i - 1]; + const b = data[i]; + if (selector) + return 0.5 * (selector(a) + selector(b)); + return 0.5 * (a + b); + } + + const z = data[(len - 1) >> 1]; + if (selector) + return selector(z); -const sortNumbers = (num1, num2) => { - return num1 - num2 + return z; } export { averageMedian } diff --git a/Maths/test/AverageMedian.test.js b/Maths/test/AverageMedian.test.js index 7e525fa5f1..a5eb0702dc 100644 --- a/Maths/test/AverageMedian.test.js +++ b/Maths/test/AverageMedian.test.js @@ -1,21 +1,83 @@ import { averageMedian } from '../AverageMedian' -test('should return the median of an array of numbers:', () => { - const medianValue = averageMedian([1, 2, 6, 4, 5]) - expect(medianValue).toBe(4) -}) - -test('should return the median of an array of numbers:', () => { - const medianValue = averageMedian([8, 9, 1, 2, 5, 10, 11]) - expect(medianValue).toBe(8) -}) - -test('should return the median of an array of numbers:', () => { - const medianValue = averageMedian([15, 18, 3, 9, 13, 5]) - expect(medianValue).toBe(11) -}) - -test('should return the median of an array of numbers:', () => { - const medianValue = averageMedian([1, 2, 3, 4, 6, 8]) - expect(medianValue).toBe(3.5) -}) +describe('math median tests', () => { + // ---------------------------------------------------------------------- + test('given empty array then median is undefined', () => { + expect(averageMedian([])).toBeUndefined(); + }); + // ---------------------------------------------------------------------- + test('given single array then median is found', () => { + expect(averageMedian([1])).toBe(1); + }); + // ---------------------------------------------------------------------- + test('given array then median not changed the origin', () => { + const src = [1,2,1,2,0,2]; + averageMedian([src]); + expect(src).toEqual([1,2,1,2,0,2]); + }); + // ---------------------------------------------------------------------- + test('given array when selector defined then median not changed the origin', () => { + const src = [1,2,1,2,0,2]; + averageMedian([src],{selector:_x=>_x}); + expect(src).toEqual([1,2,1,2,0,2]); + }); + // ---------------------------------------------------------------------- + test('given single array when selector defined then median is found', () => { + expect(averageMedian(["abc"], {selector: _x => _x.length})).toBe(3); + }); + // ---------------------------------------------------------------------- + test('given sorted array then median is found', () => { + expect(averageMedian([1],{sort:false})).toBe(1); + expect(averageMedian([1,2],{sort:false})).toBe(1.5); + expect(averageMedian([1,2,5],{sort:false})).toBe(2); + expect(averageMedian([1,2,5,5],{sort:false})).toBe(3.5); + expect(averageMedian([1,2,5,5,5],{sort:false})).toBe(5); + }); + // ---------------------------------------------------------------------- + test('given sorted array when selector defined then median is found', () => { + expect(averageMedian([1],{sort:false,selector:_x=>_x})).toBe(1); + expect(averageMedian([1,2],{sort:false,selector:_x=>_x})).toBe(1.5); + expect(averageMedian([1,2,5],{sort:false,selector:_x=>_x})).toBe(2); + expect(averageMedian([1,2,5,5],{sort:false,selector:_x=>_x})).toBe(3.5); + expect(averageMedian([1,2,5,5,5],{sort:false,selector:_x=>_x})).toBe(5); + }); + // ---------------------------------------------------------------------- + test('given not sorted array then median is found', () => { + expect(averageMedian([1])).toBe(1); + expect(averageMedian([2,1])).toBe(1.5); + expect(averageMedian([5,1,2])).toBe(2); + expect(averageMedian([5,2,1,5])).toBe(3.5); + expect(averageMedian([5,1,5,2,5])).toBe(5); + }); + // ---------------------------------------------------------------------- + test('given not sorted array when selector defined then median is found', () => { + expect(averageMedian([1],{selector:_x=>_x})).toBe(1); + expect(averageMedian([2,1],{selector:_x=>_x})).toBe(1.5); + expect(averageMedian([5,1,2],{selector:_x=>_x})).toBe(2); + expect(averageMedian([5,2,1,5],{selector:_x=>_x})).toBe(3.5); + expect(averageMedian([5,1,5,2,5],{selector:_x=>_x})).toBe(5); + }); + // ---------------------------------------------------------------------- + test('given empty generator then median is undefined', () => { + const src = function*(){} + expect(averageMedian(src())).toBeUndefined(); + }); + // ---------------------------------------------------------------------- + test('given generator then median is found', () => { + const src = function*(){ + yield 1; + yield -1; + yield 0; + } + expect(averageMedian(src())).toBe(0); + }); + // ---------------------------------------------------------------------- + test('given string generator then median string length is found', () => { + const src = function*(){ + yield "abc"; + yield "de"; + yield "qwertyq"; + } + expect(averageMedian(src(),{selector:_x=>_x.length})).toBe(3); + }); +}); \ No newline at end of file From ace5b8cbdc95b16c41df17ad139d490665be3ee9 Mon Sep 17 00:00:00 2001 From: RuSaG0 Date: Sun, 19 Dec 2021 21:10:15 +0300 Subject: [PATCH 2/4] [/pull/869] make fn pure --- Maths/AverageMedian.js | 85 +++++-------------------- Maths/test/AverageMedian.test.js | 106 ++++++++----------------------- 2 files changed, 40 insertions(+), 151 deletions(-) diff --git a/Maths/AverageMedian.js b/Maths/AverageMedian.js index 9e49acd2ec..2a6a99a9c5 100644 --- a/Maths/AverageMedian.js +++ b/Maths/AverageMedian.js @@ -1,75 +1,20 @@ -/* - * Median: https://en.wikipedia.org/wiki/Median - * - * function averageMedian - * to find the median value of an array of numbers - * the numbers in an array will be sorted in ascending order by the function sortNumbers - * if the length of the array is even number, the median value will be the average of the two middle numbers - * else if the length of the array is odd number, the median value will be the middle number in the array - */ - -const toArray = (_iterable, _selector) => { - const res = []; - if(!_selector) { - for (const x of _iterable) - res.push(x); - } - else { - for (const x of _iterable) - res.push(_selector(x)); - } - return res; -}; - -const averageMedian = (_arrayOrIterable, {sort, selector} = {}) => { - let array = _arrayOrIterable; - - const isArray = Array.isArray(_arrayOrIterable); - if(!isArray) - array = toArray(array); - - const len = array.length; - if (len <= 0) - return undefined; - if (len === 1) { - if (selector) - return selector(array[0]); - return array[0]; - } - - if (len === 2) { - const a = array[0]; - const b = array[1]; - if (selector) - return 0.5 * (selector(a) + selector(b)); - return 0.5 * (a + b); - } - - let data = array; - if (sort !== false) { - if(isArray) - data = [...array]; - - if (selector) - data.sort((_x, _y) => selector(_x) - selector(_y)); - else - data.sort(); +const averageMedian = (_numbers) => { + let numbers = [..._numbers]; + let median = 0 + const numLength = numbers.length + numbers = numbers.sort(sortNumbers) + + if (numLength % 2 === 0) { + median = (numbers[numLength / 2 - 1] + numbers[numLength / 2]) / 2 + } else { + median = numbers[(numLength - 1) / 2] } - if (len % 2 === 0) { - const i = len / 2; - const a = data[i - 1]; - const b = data[i]; - if (selector) - return 0.5 * (selector(a) + selector(b)); - return 0.5 * (a + b); - } - - const z = data[(len - 1) >> 1]; - if (selector) - return selector(z); + return median; +} - return z; +const sortNumbers = (num1, num2) => { + return num1 - num2 } -export { averageMedian } +export { averageMedian } \ No newline at end of file diff --git a/Maths/test/AverageMedian.test.js b/Maths/test/AverageMedian.test.js index a5eb0702dc..2a8a4db91a 100644 --- a/Maths/test/AverageMedian.test.js +++ b/Maths/test/AverageMedian.test.js @@ -1,83 +1,27 @@ import { averageMedian } from '../AverageMedian' -describe('math median tests', () => { - // ---------------------------------------------------------------------- - test('given empty array then median is undefined', () => { - expect(averageMedian([])).toBeUndefined(); - }); - // ---------------------------------------------------------------------- - test('given single array then median is found', () => { - expect(averageMedian([1])).toBe(1); - }); - // ---------------------------------------------------------------------- - test('given array then median not changed the origin', () => { - const src = [1,2,1,2,0,2]; - averageMedian([src]); - expect(src).toEqual([1,2,1,2,0,2]); - }); - // ---------------------------------------------------------------------- - test('given array when selector defined then median not changed the origin', () => { - const src = [1,2,1,2,0,2]; - averageMedian([src],{selector:_x=>_x}); - expect(src).toEqual([1,2,1,2,0,2]); - }); - // ---------------------------------------------------------------------- - test('given single array when selector defined then median is found', () => { - expect(averageMedian(["abc"], {selector: _x => _x.length})).toBe(3); - }); - // ---------------------------------------------------------------------- - test('given sorted array then median is found', () => { - expect(averageMedian([1],{sort:false})).toBe(1); - expect(averageMedian([1,2],{sort:false})).toBe(1.5); - expect(averageMedian([1,2,5],{sort:false})).toBe(2); - expect(averageMedian([1,2,5,5],{sort:false})).toBe(3.5); - expect(averageMedian([1,2,5,5,5],{sort:false})).toBe(5); - }); - // ---------------------------------------------------------------------- - test('given sorted array when selector defined then median is found', () => { - expect(averageMedian([1],{sort:false,selector:_x=>_x})).toBe(1); - expect(averageMedian([1,2],{sort:false,selector:_x=>_x})).toBe(1.5); - expect(averageMedian([1,2,5],{sort:false,selector:_x=>_x})).toBe(2); - expect(averageMedian([1,2,5,5],{sort:false,selector:_x=>_x})).toBe(3.5); - expect(averageMedian([1,2,5,5,5],{sort:false,selector:_x=>_x})).toBe(5); - }); - // ---------------------------------------------------------------------- - test('given not sorted array then median is found', () => { - expect(averageMedian([1])).toBe(1); - expect(averageMedian([2,1])).toBe(1.5); - expect(averageMedian([5,1,2])).toBe(2); - expect(averageMedian([5,2,1,5])).toBe(3.5); - expect(averageMedian([5,1,5,2,5])).toBe(5); - }); - // ---------------------------------------------------------------------- - test('given not sorted array when selector defined then median is found', () => { - expect(averageMedian([1],{selector:_x=>_x})).toBe(1); - expect(averageMedian([2,1],{selector:_x=>_x})).toBe(1.5); - expect(averageMedian([5,1,2],{selector:_x=>_x})).toBe(2); - expect(averageMedian([5,2,1,5],{selector:_x=>_x})).toBe(3.5); - expect(averageMedian([5,1,5,2,5],{selector:_x=>_x})).toBe(5); - }); - // ---------------------------------------------------------------------- - test('given empty generator then median is undefined', () => { - const src = function*(){} - expect(averageMedian(src())).toBeUndefined(); - }); - // ---------------------------------------------------------------------- - test('given generator then median is found', () => { - const src = function*(){ - yield 1; - yield -1; - yield 0; - } - expect(averageMedian(src())).toBe(0); - }); - // ---------------------------------------------------------------------- - test('given string generator then median string length is found', () => { - const src = function*(){ - yield "abc"; - yield "de"; - yield "qwertyq"; - } - expect(averageMedian(src(),{selector:_x=>_x.length})).toBe(3); - }); -}); \ No newline at end of file +test('should return the median of an array of numbers:', () => { + const medianValue = averageMedian([1, 2, 6, 4, 5]) + expect(medianValue).toBe(4) +}) + +test('should return the median of an array of numbers:', () => { + const medianValue = averageMedian([8, 9, 1, 2, 5, 10, 11]) + expect(medianValue).toBe(8) +}) + +test('should return the median of an array of numbers:', () => { + const medianValue = averageMedian([15, 18, 3, 9, 13, 5]) + expect(medianValue).toBe(11) +}) + +test('should return the median of an array of numbers:', () => { + const medianValue = averageMedian([1, 2, 3, 4, 6, 8]) + expect(medianValue).toBe(3.5) +}) + +test('shouldn`t change source array', () => { + const sourceArray = [3, 2, 1, 4, 6, 8]; + averageMedian(sourceArray) + expect(sourceArray).toEqual([3, 2, 1, 4, 6, 8]); +}) \ No newline at end of file From ce5e11535416841b49fbb256d701f6d87a92b8aa Mon Sep 17 00:00:00 2001 From: RuSaG0 Date: Mon, 20 Dec 2021 13:02:35 +0300 Subject: [PATCH 3/4] [/pull/869/] pure averageMedian fn --- Maths/AverageMedian.js | 12 +++++++++++- Maths/test/AverageMedian.test.js | 6 ------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Maths/AverageMedian.js b/Maths/AverageMedian.js index 2a6a99a9c5..b02042918d 100644 --- a/Maths/AverageMedian.js +++ b/Maths/AverageMedian.js @@ -1,3 +1,13 @@ +/* + * Median: https://en.wikipedia.org/wiki/Median + * + * function averageMedian + * to find the median value of an array of numbers + * the numbers in an array will be sorted in ascending order by the function sortNumbers + * if the length of the array is even number, the median value will be the average of the two middle numbers + * else if the length of the array is odd number, the median value will be the middle number in the array + */ + const averageMedian = (_numbers) => { let numbers = [..._numbers]; let median = 0 @@ -10,7 +20,7 @@ const averageMedian = (_numbers) => { median = numbers[(numLength - 1) / 2] } - return median; + return median } const sortNumbers = (num1, num2) => { diff --git a/Maths/test/AverageMedian.test.js b/Maths/test/AverageMedian.test.js index 2a8a4db91a..7a071f3aa3 100644 --- a/Maths/test/AverageMedian.test.js +++ b/Maths/test/AverageMedian.test.js @@ -18,10 +18,4 @@ test('should return the median of an array of numbers:', () => { test('should return the median of an array of numbers:', () => { const medianValue = averageMedian([1, 2, 3, 4, 6, 8]) expect(medianValue).toBe(3.5) -}) - -test('shouldn`t change source array', () => { - const sourceArray = [3, 2, 1, 4, 6, 8]; - averageMedian(sourceArray) - expect(sourceArray).toEqual([3, 2, 1, 4, 6, 8]); }) \ No newline at end of file From 57dfbd6a0e77e5e8c9f50c69eeec55ceda15d35b Mon Sep 17 00:00:00 2001 From: RuSaG0 Date: Mon, 20 Dec 2021 17:51:19 +0300 Subject: [PATCH 4/4] [/pull/869] formatter --- Maths/AverageMedian.js | 6 +++--- Maths/test/AverageMedian.test.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Maths/AverageMedian.js b/Maths/AverageMedian.js index b02042918d..3be6c551fc 100644 --- a/Maths/AverageMedian.js +++ b/Maths/AverageMedian.js @@ -8,8 +8,8 @@ * else if the length of the array is odd number, the median value will be the middle number in the array */ -const averageMedian = (_numbers) => { - let numbers = [..._numbers]; +const averageMedian = (sourceArrayOfNumbers) => { + let numbers = [...sourceArrayOfNumbers] let median = 0 const numLength = numbers.length numbers = numbers.sort(sortNumbers) @@ -27,4 +27,4 @@ const sortNumbers = (num1, num2) => { return num1 - num2 } -export { averageMedian } \ No newline at end of file +export { averageMedian } diff --git a/Maths/test/AverageMedian.test.js b/Maths/test/AverageMedian.test.js index 7a071f3aa3..7e525fa5f1 100644 --- a/Maths/test/AverageMedian.test.js +++ b/Maths/test/AverageMedian.test.js @@ -18,4 +18,4 @@ test('should return the median of an array of numbers:', () => { test('should return the median of an array of numbers:', () => { const medianValue = averageMedian([1, 2, 3, 4, 6, 8]) expect(medianValue).toBe(3.5) -}) \ No newline at end of file +})