UNPKG

3.1 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.minMax = minMax;
7exports.indicesOfNearest = indicesOfNearest;
8exports.indexOfNearest = indexOfNearest;
9function minMax(arr) {
10 var len = arr.length;
11 var min = Infinity;
12 var max = -Infinity;
13 while (len--) {
14 var el = arr[len];
15 if (el == null) {
16 // do nothing
17 } else if (el < min) {
18 min = el;
19 } else if (el > max) {
20 max = el;
21 }
22 }
23 if (min === Infinity) {
24 min = max;
25 } else if (max === -Infinity) {
26 max = min;
27 }
28 if (min === Infinity || min === -Infinity) {
29 // all values were null
30 min = null;
31 max = null;
32 }
33 return [min, max];
34}
35
36/**
37 * Return the indices of the two neighbors in the sorted array closest to the given number.
38 *
39 * @example
40 * var a = [2,5,8,12,13]
41 * var i = CovUtils.indicesOfNearest(a, 6)
42 * // i == [1,2]
43 * var j = CovUtils.indicesOfNearest(a, 5)
44 * // j == [1,1]
45 * var k = CovUtils.indicesOfNearest(a, 50)
46 * // k == [4,4]
47 *
48 * @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.
49 * @param {number} x The target number.
50 * @return {[lo,hi]} The indices of the two closest values, may be equal.
51 * If `x` exists in the array, both neighbors point to `x`.
52 * If `x` is lower (greater if descending) than the first value, both neighbors point to 0.
53 * If `x` is greater (lower if descending) than the last value, both neighbors point to the last index.
54 */
55function indicesOfNearest(a, x) {
56 if (a.length === 0) {
57 throw new Error('Array must have at least one element');
58 }
59 var lo = -1;
60 var hi = a.length;
61 var ascending = a.length === 1 || a[0] < a[1];
62 // we have two separate code paths to help the runtime optimize the loop
63 if (ascending) {
64 while (hi - lo > 1) {
65 var mid = Math.round((lo + hi) / 2);
66 if (a[mid] <= x) {
67 lo = mid;
68 } else {
69 hi = mid;
70 }
71 }
72 } else {
73 while (hi - lo > 1) {
74 var _mid = Math.round((lo + hi) / 2);
75 if (a[_mid] >= x) {
76 // here's the difference
77 lo = _mid;
78 } else {
79 hi = _mid;
80 }
81 }
82 }
83 if (a[lo] === x) hi = lo;
84 if (lo === -1) lo = hi;
85 if (hi === a.length) hi = lo;
86 return [lo, hi];
87}
88
89/**
90 * Return the index of the value closest to the given number in a sorted array.
91 *
92 * @example
93 * var a = [2,5,8,12,13]
94 * var i = CovUtils.indexOfNearest(a, 6)
95 * // i == 1
96 * var j = CovUtils.indexOfNearest(a, 7)
97 * // j == 2
98 * var k = CovUtils.indexOfNearest(a, 50)
99 * // k == 4
100 *
101 * @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.
102 * @param {number} x The target number.
103 * @return {number} The array index whose value is closest to `x`.
104 * If `x` happens to be exactly between two values, then the lower index is returned.
105 */
106function indexOfNearest(a, x) {
107 var i = indicesOfNearest(a, x);
108 var lo = i[0];
109 var hi = i[1];
110 if (Math.abs(x - a[lo]) <= Math.abs(x - a[hi])) {
111 return lo;
112 } else {
113 return hi;
114 }
115}
\No newline at end of file