UNPKG

@rimbu/base

Version:

Utilities to implement Rimbu collections

405 lines 12.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.splice = exports.insert = exports.mod = exports.update = exports.last = exports.prepend = exports.reverse = exports.append = void 0; exports._appendNew = _appendNew; exports._appendOld = _appendOld; exports.concat = concat; exports._reverseNew = _reverseNew; exports._reverseOld = _reverseOld; exports.forEach = forEach; exports.map = map; exports.reverseMap = reverseMap; exports._prependNew = _prependNew; exports._prependOld = _prependOld; exports._lastNew = _lastNew; exports._lastOld = _lastOld; exports._updateNew = _updateNew; exports._updateOld = _updateOld; exports._modNew = _modNew; exports._modOld = _modOld; exports._insertNew = _insertNew; exports._insertOld = _insertOld; exports.tail = tail; exports.init = init; exports._spliceNew = _spliceNew; exports._spliceOld = _spliceOld; exports.copySparse = copySparse; exports.mapSparse = mapSparse; var tslib_1 = require("tslib"); var common_1 = require("@rimbu/common"); /** * Internal helper that appends a value using the modern immutable `toSpliced` API. * @internal * @typeparam T - the array element type * @param array - the source array (not mutated) * @param value - the value to append * @returns a new non-empty array with the value at the end */ function _appendNew(array, value) { return array.toSpliced(array.length, 0, value); } /** * Internal helper that appends a value by cloning and pushing (legacy fallback). * @internal * @typeparam T - the array element type * @param array - the source array (not mutated) * @param value - the value to append * @returns a new non-empty array with the value at the end */ function _appendOld(array, value) { var clone = array.slice(); clone.push(value); return clone; } /** * Returns a copy of the array with the given value appended. * Chooses an implementation depending on environment capabilities. * @typeparam T - the array element type * @param array - the source array (not mutated) * @param value - the value to append * @returns a new array with the value at the end */ exports.append = "toSpliced" in Array.prototype ? _appendNew : _appendOld; /** * Returns the concatenation of two arrays, reusing an input array when the other is empty. * @typeparam T - the array element type * @param first - the first array * @param second - the second array * @returns a new array containing all elements of both arrays (or one of the originals if the other is empty) */ function concat(first, second) { if (first.length === 0) return second; if (second.length === 0) return first; return first.concat(second); } /** * Internal helper to create a reversed copy using modern `toReversed` with optional slicing. * @internal */ function _reverseNew(array, start, end) { var source = undefined !== start || undefined !== end ? array.slice(start !== null && start !== void 0 ? start : 0, (end !== null && end !== void 0 ? end : array.length - 1) + 1) : array; return source.toReversed(); } /** * Internal helper to create a reversed copy using manual iteration (legacy fallback). * @internal */ function _reverseOld(array, start, end) { var _start = start !== null && start !== void 0 ? start : 0; var _end = end !== null && end !== void 0 ? end : array.length - 1; var length = _end - _start + 1; var res = []; var arrayIndex = _start - 1; var resIndex = length - 1; while (++arrayIndex <= _end) res[resIndex--] = array[arrayIndex]; return res; } /** * Returns a copy of the array (or a slice) with elements in reversed order. * @typeparam T - array element type * @param array - the source array * @param start - optional start index (inclusive) * @param end - optional end index (inclusive) */ exports.reverse = 'toReversed' in Array.prototype ? _reverseNew : _reverseOld; /** * Performs the given function for each element of the array, optionally in reverse order. * Halting is supported through the provided `TraverseState`. * @typeparam T - element type * @param array - the source array * @param f - callback receiving (value, sequential index, halt) * @param state - traversal state (created if omitted) * @param reversed - whether to traverse in reverse order */ function forEach(array, f, state, reversed) { if (state === void 0) { state = (0, common_1.TraverseState)(); } if (reversed === void 0) { reversed = false; } if (state.halted) return; var halt = state.halt; if (reversed) { var i = array.length; while (!state.halted && --i >= 0) { f(array[i], state.nextIndex(), halt); } } else { var length = array.length; var i = -1; while (!state.halted && ++i < length) { f(array[i], state.nextIndex(), halt); } } } /** * Returns a copy of the array where the given function is applied to each element. * Supports an index offset useful for composed traversals. * @typeparam T - source element type * @typeparam R - result element type * @param array - the source array * @param f - the mapping function * @param indexOffset - optional start index value passed to `f` */ function map(array, f, indexOffset) { if (indexOffset === void 0) { indexOffset = 0; } if (indexOffset === 0) { // without offset, can use standard array map return array.map(f); } var result = []; var index = indexOffset; var i = -1; var length = array.length; while (++i < length) { result[i] = f(array[i], index++); } return result; } /** * Returns a copy of the array where the given function is applied to each element in reverse order. * @typeparam T - source element type * @typeparam R - result element type * @param array - the source array * @param f - the mapping function * @param indexOffset - optional index offset passed to `f` */ function reverseMap(array, f, indexOffset) { if (indexOffset === void 0) { indexOffset = 0; } var result = []; var index = indexOffset; var arrayIndex = array.length; var resultIndex = 0; while (--arrayIndex >= 0) result[resultIndex++] = f(array[arrayIndex], index++); return result; } /** * Internal helper to prepend a value using `toSpliced`. * @internal */ function _prependNew(array, value) { return array.toSpliced(0, 0, value); } /** * Internal helper to prepend a value using legacy cloning. * @internal */ function _prependOld(array, value) { var clone = array.slice(); clone.unshift(value); return clone; } /** * Returns a copy of the array with the given value inserted at the start. * @typeparam T - element type * @param array - the source array * @param value - value to insert at index 0 */ exports.prepend = "toSpliced" in Array.prototype ? _prependNew : _prependOld; /** * Internal helper to obtain the last element using modern `at`. * @internal */ function _lastNew(arr) { return arr.at(-1); } /** * Internal helper to obtain the last element using index arithmetic. * @internal */ function _lastOld(arr) { return arr[arr.length - 1]; } /** * Returns the last element of the array. * @typeparam T - element type * @param arr - the array */ exports.last = "at" in Array.prototype ? _lastNew : _lastOld; /** * Internal helper implementing an immutable index update via `with`. * @internal */ function _updateNew(arr, index, updater) { if (index < 0 || index >= arr.length) { return arr; } var curValue = arr[index]; var newValue = (0, common_1.Update)(curValue, updater); if (Object.is(newValue, curValue)) { return arr; } return arr.with(index, newValue); } /** * Internal helper implementing an immutable index update via cloning. * @internal */ function _updateOld(arr, index, updater) { if (index < 0 || index >= arr.length) { return arr; } var curValue = arr[index]; var newValue = (0, common_1.Update)(curValue, updater); if (Object.is(newValue, curValue)) { return arr; } var newArr = arr.slice(); newArr[index] = newValue; return newArr; } /** * Returns a copy of the array where the element at the given index is replaced using the provided updater. * If the result value is identical (by `Object.is`) the original array is returned. * @typeparam T - element type * @param arr - the source array * @param index - the index to update * @param updater - value or function update description */ exports.update = "with" in Array.prototype ? _updateNew : _updateOld; /** * Internal helper applying a modifier function via `with`. * @internal */ function _modNew(arr, index, f) { if (index < 0 || index >= arr.length) { return arr; } var curValue = arr[index]; var newValue = f(curValue); if (Object.is(newValue, curValue)) { return arr; } return arr.with(index, newValue); } /** * Internal helper applying a modifier function via cloning. * @internal */ function _modOld(arr, index, f) { if (index < 0 || index >= arr.length) { return arr; } var curValue = arr[index]; var newValue = f(curValue); if (Object.is(newValue, curValue)) { return arr; } var newArr = arr.slice(); newArr[index] = newValue; return newArr; } /** * Returns a copy of the array where the element at the given index is transformed by a modifier function. * If the result value is identical (by `Object.is`) the original array is returned. * @typeparam T - element type * @param arr - the source array * @param index - the index to modify * @param f - modifier function receiving the current value */ exports.mod = "with" in Array.prototype ? _modNew : _modOld; /** * Internal helper for inserting a value using `toSpliced`. * @internal */ function _insertNew(arr, index, value) { return arr.toSpliced(index, 0, value); } /** * Internal helper for inserting a value using legacy `splice` on a clone. * @internal */ function _insertOld(arr, index, value) { var clone = arr.slice(); clone.splice(index, 0, value); return clone; } /** * Returns a copy of the array where at the given index the provided value is inserted. * @typeparam T - element type * @param arr - the source array * @param index - insertion index * @param value - value to insert */ exports.insert = "toSpliced" in Array.prototype ? _insertNew : _insertOld; /** * Returns a copy of the array without its first element. * @typeparam T - element type * @param arr - the source array */ function tail(arr) { return arr.slice(1); } /** * Returns a copy of the array without its last element. * @typeparam T - element type * @param arr - the source array */ function init(arr) { return arr.slice(0, arr.length - 1); } /** * Internal helper providing an immutable `splice` using `toSpliced`. * @internal */ function _spliceNew(arr, start, deleteCount) { var items = []; for (var _i = 3; _i < arguments.length; _i++) { items[_i - 3] = arguments[_i]; } return arr.toSpliced.apply(arr, tslib_1.__spreadArray([start, deleteCount], tslib_1.__read(items), false)); } /** * Internal helper providing an immutable `splice` via cloning. * @internal */ function _spliceOld(arr, start, deleteCount) { var items = []; for (var _i = 3; _i < arguments.length; _i++) { items[_i - 3] = arguments[_i]; } var clone = arr.slice(); clone.splice.apply(clone, tslib_1.__spreadArray([start, deleteCount], tslib_1.__read(items), false)); return clone; } /** * Immutable version of the array `.splice` command, always returning a new array. * @typeparam T - element type * @param arr - the source array * @param start - start index * @param deleteCount - number of elements to delete * @param items - optional items to insert */ exports.splice = "toSpliced" in Array.prototype ? _spliceNew : _spliceOld; /** * Returns a copy of a (potentially) sparse array preserving sparsity (skips holes). * @typeparam T - element type * @param arr - the source sparse array */ function copySparse(arr) { var clone = []; for (var key in arr) { clone[key] = arr[key]; } return clone; } /** * Returns a copy of a sparse array applying the given function to each present element, preserving holes. * @typeparam T - source element type * @typeparam T2 - result element type * @param arr - the source sparse array * @param f - mapping function */ function mapSparse(arr, f) { var result = Array(arr.length); for (var key in arr) { result[key] = f(arr[key], key); } return result; } //# sourceMappingURL=arr.cjs.map