1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.minMax = minMax;
|
7 | exports.indicesOfNearest = indicesOfNearest;
|
8 | exports.indexOfNearest = indexOfNearest;
|
9 | function 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 | */
|
55 | function 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 | */
|
106 | function 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 |