121 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| var __importDefault = (this && this.__importDefault) || function (mod) {
 | |
|     return (mod && mod.__esModule) ? mod : { "default": mod };
 | |
| };
 | |
| Object.defineProperty(exports, "__esModule", { value: true });
 | |
| exports.generate = exports.compile = void 0;
 | |
| var boolbase_1 = __importDefault(require("boolbase"));
 | |
| /**
 | |
|  * Returns a function that checks if an elements index matches the given rule
 | |
|  * highly optimized to return the fastest solution.
 | |
|  *
 | |
|  * @param parsed A tuple [a, b], as returned by `parse`.
 | |
|  * @returns A highly optimized function that returns whether an index matches the nth-check.
 | |
|  * @example
 | |
|  *
 | |
|  * ```js
 | |
|  * const check = nthCheck.compile([2, 3]);
 | |
|  *
 | |
|  * check(0); // `false`
 | |
|  * check(1); // `false`
 | |
|  * check(2); // `true`
 | |
|  * check(3); // `false`
 | |
|  * check(4); // `true`
 | |
|  * check(5); // `false`
 | |
|  * check(6); // `true`
 | |
|  * ```
 | |
|  */
 | |
| function compile(parsed) {
 | |
|     var a = parsed[0];
 | |
|     // Subtract 1 from `b`, to convert from one- to zero-indexed.
 | |
|     var b = parsed[1] - 1;
 | |
|     /*
 | |
|      * When `b <= 0`, `a * n` won't be lead to any matches for `a < 0`.
 | |
|      * Besides, the specification states that no elements are
 | |
|      * matched when `a` and `b` are 0.
 | |
|      *
 | |
|      * `b < 0` here as we subtracted 1 from `b` above.
 | |
|      */
 | |
|     if (b < 0 && a <= 0)
 | |
|         return boolbase_1.default.falseFunc;
 | |
|     // When `a` is in the range -1..1, it matches any element (so only `b` is checked).
 | |
|     if (a === -1)
 | |
|         return function (index) { return index <= b; };
 | |
|     if (a === 0)
 | |
|         return function (index) { return index === b; };
 | |
|     // When `b <= 0` and `a === 1`, they match any element.
 | |
|     if (a === 1)
 | |
|         return b < 0 ? boolbase_1.default.trueFunc : function (index) { return index >= b; };
 | |
|     /*
 | |
|      * Otherwise, modulo can be used to check if there is a match.
 | |
|      *
 | |
|      * Modulo doesn't care about the sign, so let's use `a`s absolute value.
 | |
|      */
 | |
|     var absA = Math.abs(a);
 | |
|     // Get `b mod a`, + a if this is negative.
 | |
|     var bMod = ((b % absA) + absA) % absA;
 | |
|     return a > 1
 | |
|         ? function (index) { return index >= b && index % absA === bMod; }
 | |
|         : function (index) { return index <= b && index % absA === bMod; };
 | |
| }
 | |
| exports.compile = compile;
 | |
| /**
 | |
|  * Returns a function that produces a monotonously increasing sequence of indices.
 | |
|  *
 | |
|  * If the sequence has an end, the returned function will return `null` after
 | |
|  * the last index in the sequence.
 | |
|  *
 | |
|  * @param parsed A tuple [a, b], as returned by `parse`.
 | |
|  * @returns A function that produces a sequence of indices.
 | |
|  * @example <caption>Always increasing (2n+3)</caption>
 | |
|  *
 | |
|  * ```js
 | |
|  * const gen = nthCheck.generate([2, 3])
 | |
|  *
 | |
|  * gen() // `1`
 | |
|  * gen() // `3`
 | |
|  * gen() // `5`
 | |
|  * gen() // `8`
 | |
|  * gen() // `11`
 | |
|  * ```
 | |
|  *
 | |
|  * @example <caption>With end value (-2n+10)</caption>
 | |
|  *
 | |
|  * ```js
 | |
|  *
 | |
|  * const gen = nthCheck.generate([-2, 5]);
 | |
|  *
 | |
|  * gen() // 0
 | |
|  * gen() // 2
 | |
|  * gen() // 4
 | |
|  * gen() // null
 | |
|  * ```
 | |
|  */
 | |
| function generate(parsed) {
 | |
|     var a = parsed[0];
 | |
|     // Subtract 1 from `b`, to convert from one- to zero-indexed.
 | |
|     var b = parsed[1] - 1;
 | |
|     var n = 0;
 | |
|     // Make sure to always return an increasing sequence
 | |
|     if (a < 0) {
 | |
|         var aPos_1 = -a;
 | |
|         // Get `b mod a`
 | |
|         var minValue_1 = ((b % aPos_1) + aPos_1) % aPos_1;
 | |
|         return function () {
 | |
|             var val = minValue_1 + aPos_1 * n++;
 | |
|             return val > b ? null : val;
 | |
|         };
 | |
|     }
 | |
|     if (a === 0)
 | |
|         return b < 0
 | |
|             ? // There are no result — always return `null`
 | |
|                 function () { return null; }
 | |
|             : // Return `b` exactly once
 | |
|                 function () { return (n++ === 0 ? b : null); };
 | |
|     if (b < 0) {
 | |
|         b += a * Math.ceil(-b / a);
 | |
|     }
 | |
|     return function () { return a * n++ + b; };
 | |
| }
 | |
| exports.generate = generate;
 | |
| //# sourceMappingURL=compile.js.map
 |