UNPKG

@rimbu/base

Version:

Utilities to implement Rimbu collections

200 lines 6.93 kB
import { TraverseState, Update } from '@rimbu/common'; export function _appendNew(array, value) { return array.toSpliced(array.length, 0, value); } export function _appendOld(array, value) { const clone = array.slice(); clone.push(value); return clone; } // Returns a copy of the array with the given value appended export const append = `toSpliced` in Array.prototype ? _appendNew : _appendOld; // Returns the concatenation of the two arrays, potentially reusing the input array if one of the arrays is empty export function concat(first, second) { if (first.length === 0) return second; if (second.length === 0) return first; return first.concat(second); } export function _reverseNew(array, start, end) { const source = undefined !== start || undefined !== end ? array.slice(start ?? 0, (end ?? array.length - 1) + 1) : array; return source.toReversed(); } export function _reverseOld(array, start, end) { const _start = start ?? 0; const _end = end ?? array.length - 1; const length = _end - _start + 1; const res = []; let arrayIndex = _start - 1; let resIndex = length - 1; while (++arrayIndex <= _end) res[resIndex--] = array[arrayIndex]; return res; } // Returns an copy of the array between the start and end indices, with the elements in reversed order. export const reverse = 'toReversed' in Array.prototype ? _reverseNew : _reverseOld; // Performs given function on each element of the array, in reverse order if 'reversed' is true. export function forEach(array, f, state = TraverseState(), reversed = false) { if (state.halted) return; const { halt } = state; if (reversed) { let i = array.length; while (!state.halted && --i >= 0) { f(array[i], state.nextIndex(), halt); } } else { const length = array.length; let i = -1; while (!state.halted && ++i < length) { f(array[i], state.nextIndex(), halt); } } } // Returns a copy of the array where given function is applied to each element export function map(array, f, indexOffset = 0) { if (indexOffset === 0) { // without offset, can use standard array map return array.map(f); } const result = []; let index = indexOffset; let i = -1; const length = array.length; while (++i < length) { result[i] = f(array[i], index++); } return result; } // Returns a copy of the array where given functio is applied to each element in reverse order export function reverseMap(array, f, indexOffset = 0) { const result = []; let index = indexOffset; let arrayIndex = array.length; let resultIndex = 0; while (--arrayIndex >= 0) result[resultIndex++] = f(array[arrayIndex], index++); return result; } export function _prependNew(array, value) { return array.toSpliced(0, 0, value); } export function _prependOld(array, value) { const clone = array.slice(); clone.unshift(value); return clone; } // Returns a copy of the given array with the given value added at the start export const prepend = `toSpliced` in Array.prototype ? _prependNew : _prependOld; export function _lastNew(arr) { return arr.at(-1); } export function _lastOld(arr) { return arr[arr.length - 1]; } // Returns the last element of the array export const last = `at` in Array.prototype ? _lastNew : _lastOld; export function _updateNew(arr, index, updater) { if (index < 0 || index >= arr.length) { return arr; } const curValue = arr[index]; const newValue = Update(curValue, updater); if (Object.is(newValue, curValue)) { return arr; } return arr.with(index, newValue); } export function _updateOld(arr, index, updater) { if (index < 0 || index >= arr.length) { return arr; } const curValue = arr[index]; const newValue = Update(curValue, updater); if (Object.is(newValue, curValue)) { return arr; } const newArr = arr.slice(); newArr[index] = newValue; return newArr; } // Returns a copy of the array where the element at given index is replaced by the given updater. // If the new element is the same as the old element, the original array is returned export const update = `with` in Array.prototype ? _updateNew : _updateOld; export function _modNew(arr, index, f) { if (index < 0 || index >= arr.length) { return arr; } const curValue = arr[index]; const newValue = f(curValue); if (Object.is(newValue, curValue)) { return arr; } return arr.with(index, newValue); } export function _modOld(arr, index, f) { if (index < 0 || index >= arr.length) { return arr; } const curValue = arr[index]; const newValue = f(curValue); if (Object.is(newValue, curValue)) { return arr; } const newArr = arr.slice(); newArr[index] = newValue; return newArr; } // Returns a copy of the array where the element at given index is replaced by applying given function. // If the new element is the same as the old element, the original array is returned export const mod = `with` in Array.prototype ? _modNew : _modOld; export function _insertNew(arr, index, value) { return arr.toSpliced(index, 0, value); } export function _insertOld(arr, index, value) { const clone = arr.slice(); clone.splice(index, 0, value); return clone; } // Returns a copy of the array where at given index the given value is inserted export const insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld; // Returns a copy of the array, without its first element export function tail(arr) { return arr.slice(1); } // Returns a copy of the array, without its last element export function init(arr) { return arr.slice(0, arr.length - 1); } export function _spliceNew(arr, start, deleteCount, ...items) { return arr.toSpliced(start, deleteCount, ...items); } export function _spliceOld(arr, start, deleteCount, ...items) { const clone = arr.slice(); clone.splice(start, deleteCount, ...items); return clone; } // Immutable version of the array .splice command, always returns a new array export const splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld; // Returns a copy of the array, where its 'sparse' property is kept (sparse = not all indices have a value) export function copySparse(arr) { const clone = []; for (const key in arr) { clone[key] = arr[key]; } return clone; } // Returns a copy of the array with given function applied to each element, where its 'sparse' property is kept // (sparse = not all indices have a value) export function mapSparse(arr, f) { const result = Array(arr.length); for (const key in arr) { result[key] = f(arr[key], key); } return result; } //# sourceMappingURL=arr.mjs.map