diff --git a/Maths/FindMode.js b/Maths/FindMode.js new file mode 100644 index 0000000000..16b5293f8a --- /dev/null +++ b/Maths/FindMode.js @@ -0,0 +1,30 @@ +/** + * @function findMode + * @description Finds the mode of an array of numbers. The mode is the + * value that appears most frequently. If multiple values appear the + * same number of times, all of them are returned. + * @param {number[]} arr - An array of numbers + * @returns {number[]} - An array containing the mode value(s) + * @see https://en.wikipedia.org/wiki/Mode_(statistics) + * @example findMode([1, 2, 2, 3]) => [2] + * @example findMode([1, 1, 2, 2]) => [1, 2] + * @example findMode([1, 2, 3]) => [1, 2, 3] + */ +const findMode = (arr) => { + if (!Array.isArray(arr) || arr.length === 0) { + throw new TypeError('Input must be a non-empty array') + } + if (!arr.every((n) => typeof n === 'number' && !isNaN(n))) { + throw new TypeError('All elements must be numbers') + } + const frequency = {} + for (const num of arr) { + frequency[num] = (frequency[num] || 0) + 1 + } + const maxFreq = Math.max(...Object.values(frequency)) + return Object.keys(frequency) + .filter((key) => frequency[key] === maxFreq) + .map(Number) +} + +export { findMode } diff --git a/Maths/test/FindMode.test.js b/Maths/test/FindMode.test.js new file mode 100644 index 0000000000..b42216618b --- /dev/null +++ b/Maths/test/FindMode.test.js @@ -0,0 +1,43 @@ +import { findMode } from '../FindMode.js' + +describe('findMode', () => { + test('findMode([1, 2, 2, 3]) returns [2]', () => { + expect(findMode([1, 2, 2, 3])).toEqual([2]) + }) + + test('findMode([1, 1, 2, 2]) returns [1, 2]', () => { + expect(findMode([1, 1, 2, 2])).toEqual([1, 2]) + }) + + test('findMode([1, 2, 3]) returns [1, 2, 3]', () => { + expect(findMode([1, 2, 3])).toEqual([1, 2, 3]) + }) + + test('findMode single element returns that element', () => { + expect(findMode([5])).toEqual([5]) + }) + + test('findMode([3, 3, 3]) returns [3]', () => { + expect(findMode([3, 3, 3])).toEqual([3]) + }) + + test('findMode works with negative numbers', () => { + expect(findMode([-1, -1, 2])).toEqual([-1]) + }) + + test('findMode([1, 2, 2, 3, 3]) returns [2, 3]', () => { + expect(findMode([1, 2, 2, 3, 3])).toEqual([2, 3]) + }) + + test('throws TypeError for empty array', () => { + expect(() => findMode([])).toThrow(TypeError) + }) + + test('throws TypeError for non-array input', () => { + expect(() => findMode('123')).toThrow(TypeError) + }) + + test('throws TypeError for array with non-numbers', () => { + expect(() => findMode([1, 'two', 3])).toThrow(TypeError) + }) +})