tiinvo
Version:
A library of types and utilities for your TypeScript and JavaScript projects
135 lines (134 loc) • 3.35 kB
JavaScript
//#region factories
/**
* Makes a new range from a start to an end (inclusive)
*
* If the third parameter `step` is passed, the range will increment by that step
*
* **Important**: the range accepts negative values, and the `end` does not have to be greater than the `start`.
*
* @example
*
* ```ts
* import { Range } from 'tiinvo'
*
* for (const n of Range.make(0, 10)) {
* console.log(n)
* }
*
* // will log 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
*
* for (const n of Range.make(0, 10, 2)) {
* console.log(n)
* }
*
* // will log 0, 2, 4, 6, 8, 10
*
* for (const n of Range.make(10, 0, 2)) {
* console.log(n)
* }
*
* // will log 10, 8, 6, 4, 2, 0
* ```
*
* @param start range's starting value
* @param end range's ending value
* @param step range's increment value
* @group Factories
* @since 4.0.0
*/
export const make = (start, end, step = 1) => {
step = end > start ? Math.abs(step) : -1 * Math.abs(step);
return {
start,
end,
step,
[Symbol.iterator]: () => {
let current = start;
let last = end;
return {
current,
last,
next() {
if (step > 0 ? current <= last : current >= last) {
const value = current;
current += step;
return { done: false, value };
}
else {
return { done: true, value: last };
}
}
};
}
};
};
//#endregion
//#region guards
/**
* Checks if a parameter `x` is of `Range.T` type
*
* @example
*
* ```ts
* import { Range } from 'tiinvo'
*
* Range.guard(10) // false
* Range.guard([]) // false
* Range.guard({}) // false
* Range.guard({ start: 10, end: 20 }) // false
* Range.guard({ start: 10, end: 20, step: 12 }) // false
* Range.guard(Range.make(1, 2)) // true
* ```
*
* @param x the value to check
* @returns true if `x` is a `T`, false otherwise
* @group Guardables
* @since 4.0.0
*/
export const guard = (x) => typeof x === 'object' && !!x && 'start' in x && 'end' in x && 'step' in x && Symbol.iterator in x;
export function inRange(t, a) {
if (guard(t) && typeof a === 'number') {
const { start, end } = t;
return start < end ? (end >= a && a >= start) : (end <= a && a <= start);
}
return (b) => {
const { start, end } = b;
return start < end ? (end >= t && t >= start) : (end <= t && t <= start);
};
}
export function map(t, m) {
const _map = (_t, _m) => {
const out = [];
for (const x of _t) {
out.push(_m(x));
}
return out;
};
if (guard(t) && !!m) {
return _map(t, m);
}
else if (!guard(t)) {
return (b) => _map(b, t);
}
}
;
//#endregion
//#region serializables
/**
* Converts a `Range.T` to a `number[]` array
*
* @example
*
* ```ts
* import { Range } from 'tiinvo'
*
* const r = Range.make(0, 10)
*
* Range.toArray(r) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
* ```
*
* @group Serializables
* @since 4.0.0
*/
export const toArray = Array.from;
//#endregion