1 | import { flatten } from '../../utils/array'
|
2 | import { factory } from '../../utils/factory'
|
3 |
|
4 | const name = 'mode'
|
5 | const dependencies = ['typed', 'isNaN', 'isNumeric']
|
6 |
|
7 | export 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 | })
|