@rimbu/base
Version:
Utilities to implement Rimbu collections
405 lines • 12.8 kB
JavaScript
;
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