UNPKG

2.05 kBJavaScriptView Raw
1import { flatten } from '../../utils/array'
2import { factory } from '../../utils/factory'
3
4const name = 'mode'
5const dependencies = ['typed', 'isNaN', 'isNumeric']
6
7export const createMode = /* #__PURE__ */ factory(name, dependencies, ({ typed, isNaN, isNumeric }) => {
8 /**
9 * Computes the mode of a set of numbers or a list with values(numbers or characters).
10 * If there are more than one modes, it returns a list of those values.
11 *
12 * Syntax:
13 *
14 * math.mode(a, b, c, ...)
15 * math.mode(A)
16 *
17 * Examples:
18 *
19 * math.mode(2, 1, 4, 3, 1) // returns [1]
20 * math.mode([1, 2.7, 3.2, 4, 2.7]) // returns [2.7]
21 * math.mode(1, 4, 6, 1, 6) // returns [1, 6]
22 * math.mode('a','a','b','c') // returns ["a"]
23 * math.mode(1, 1.5, 'abc') // returns [1, 1.5, "abc"]
24 *
25 * See also:
26 *
27 * median,
28 * mean
29 *
30 * @param {... *} args A single matrix
31 * @return {*} The mode of all values
32 */
33 return typed(name, {
34 'Array | Matrix': _mode,
35
36 '...': function (args) {
37 return _mode(args)
38 }
39 })
40
41 /**
42 * Calculates the mode in an 1-dimensional array
43 * @param {Array} values
44 * @return {Array} mode
45 * @private
46 */
47 function _mode (values) {
48 values = flatten(values.valueOf())
49 const num = values.length
50 if (num === 0) {
51 throw new Error('Cannot calculate mode of an empty array')
52 }
53
54 const count = {}
55 let mode = []
56 let max = 0
57 for (let i = 0; i < values.length; i++) {
58 const value = values[i]
59
60 if (isNumeric(value) && isNaN(value)) {
61 throw new Error('Cannot calculate mode of an array containing NaN values')
62 }
63
64 if (!(value in count)) {
65 count[value] = 0
66 }
67
68 count[value]++
69
70 if (count[value] === max) {
71 mode.push(value)
72 } else if (count[value] > max) {
73 max = count[value]
74 mode = [value]
75 }
76 }
77 return mode
78 }
79})