UNPKG

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