-
Notifications
You must be signed in to change notification settings - Fork 224
/
mode_fast.js
57 lines (51 loc) · 1.85 KB
/
mode_fast.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/* globals Map: false */
/**
* The [mode](https://en.wikipedia.org/wiki/Mode_%28statistics%29) is the number
* that appears in a list the highest number of times.
* There can be multiple modes in a list: in the event of a tie, this
* algorithm will return the most recently seen mode.
*
* modeFast uses a Map object to keep track of the mode, instead of the approach
* used with `mode`, a sorted array. As a result, it is faster
* than `mode` and supports any data type that can be compared with `==`.
* It also requires a
* [JavaScript environment with support for Map](https://kangax.github.io/compat-table/es6/#test-Map),
* and will throw an error if Map is not available.
*
* This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):
* a method of finding a typical or central value of a set of numbers.
*
* @param {Array<*>} x a sample of one or more data points
* @returns {?*} mode
* @throws {ReferenceError} if the JavaScript environment doesn't support Map
* @throws {Error} if x is empty
* @example
* modeFast(['rabbits', 'rabbits', 'squirrels']); // => 'rabbits'
*/
function modeFast(x) {
// This index will reflect the incidence of different values, indexing
// them like
// { value: count }
const index = new Map();
// A running `mode` and the number of times it has been encountered.
let mode;
let modeCount = 0;
for (let i = 0; i < x.length; i++) {
let newCount = index.get(x[i]);
if (newCount === undefined) {
newCount = 1;
} else {
newCount++;
}
if (newCount > modeCount) {
mode = x[i];
modeCount = newCount;
}
index.set(x[i], newCount);
}
if (modeCount === 0) {
throw new Error("mode requires at last one data point");
}
return mode;
}
export default modeFast;