UNPKG

3.81 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.generate = exports.compile = void 0;
7var boolbase_1 = __importDefault(require("boolbase"));
8/**
9 * Returns a function that checks if an elements index matches the given rule
10 * highly optimized to return the fastest solution.
11 *
12 * @param parsed A tuple [a, b], as returned by `parse`.
13 * @returns A highly optimized function that returns whether an index matches the nth-check.
14 * @example
15 *
16 * ```js
17 * const check = nthCheck.compile([2, 3]);
18 *
19 * check(0); // `false`
20 * check(1); // `false`
21 * check(2); // `true`
22 * check(3); // `false`
23 * check(4); // `true`
24 * check(5); // `false`
25 * check(6); // `true`
26 * ```
27 */
28function compile(parsed) {
29 var a = parsed[0];
30 // Subtract 1 from `b`, to convert from one- to zero-indexed.
31 var b = parsed[1] - 1;
32 /*
33 * When `b <= 0`, `a * n` won't be lead to any matches for `a < 0`.
34 * Besides, the specification states that no elements are
35 * matched when `a` and `b` are 0.
36 *
37 * `b < 0` here as we subtracted 1 from `b` above.
38 */
39 if (b < 0 && a <= 0)
40 return boolbase_1.default.falseFunc;
41 // When `a` is in the range -1..1, it matches any element (so only `b` is checked).
42 if (a === -1)
43 return function (index) { return index <= b; };
44 if (a === 0)
45 return function (index) { return index === b; };
46 // When `b <= 0` and `a === 1`, they match any element.
47 if (a === 1)
48 return b < 0 ? boolbase_1.default.trueFunc : function (index) { return index >= b; };
49 /*
50 * Otherwise, modulo can be used to check if there is a match.
51 *
52 * Modulo doesn't care about the sign, so let's use `a`s absolute value.
53 */
54 var absA = Math.abs(a);
55 // Get `b mod a`, + a if this is negative.
56 var bMod = ((b % absA) + absA) % absA;
57 return a > 1
58 ? function (index) { return index >= b && index % absA === bMod; }
59 : function (index) { return index <= b && index % absA === bMod; };
60}
61exports.compile = compile;
62/**
63 * Returns a function that produces a monotonously increasing sequence of indices.
64 *
65 * If the sequence has an end, the returned function will return `null` after
66 * the last index in the sequence.
67 *
68 * @param parsed A tuple [a, b], as returned by `parse`.
69 * @returns A function that produces a sequence of indices.
70 * @example <caption>Always increasing (2n+3)</caption>
71 *
72 * ```js
73 * const gen = nthCheck.generate([2, 3])
74 *
75 * gen() // `1`
76 * gen() // `3`
77 * gen() // `5`
78 * gen() // `8`
79 * gen() // `11`
80 * ```
81 *
82 * @example <caption>With end value (-2n+10)</caption>
83 *
84 * ```js
85 *
86 * const gen = nthCheck.generate([-2, 5]);
87 *
88 * gen() // 0
89 * gen() // 2
90 * gen() // 4
91 * gen() // null
92 * ```
93 */
94function generate(parsed) {
95 var a = parsed[0];
96 // Subtract 1 from `b`, to convert from one- to zero-indexed.
97 var b = parsed[1] - 1;
98 var n = 0;
99 // Make sure to always return an increasing sequence
100 if (a < 0) {
101 var aPos_1 = -a;
102 // Get `b mod a`
103 var minValue_1 = ((b % aPos_1) + aPos_1) % aPos_1;
104 return function () {
105 var val = minValue_1 + aPos_1 * n++;
106 return val > b ? null : val;
107 };
108 }
109 if (a === 0)
110 return b < 0
111 ? // There are no result — always return `null`
112 function () { return null; }
113 : // Return `b` exactly once
114 function () { return (n++ === 0 ? b : null); };
115 if (b < 0) {
116 b += a * Math.ceil(-b / a);
117 }
118 return function () { return a * n++ + b; };
119}
120exports.generate = generate;
121//# sourceMappingURL=compile.js.map
\No newline at end of file