All files / string/src splice.ts

100% Statements 5/5
100% Branches 10/10
100% Functions 3/3
100% Lines 5/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 562x                                                                 32x 2x 32x                     32x                  
import { mod } from "@benneq/number";
 
/**
 * Removes characters from a String, and inserts new characters in their place.
 *
 * Works like {@link Array.prototype.splice}
 *
 * @example
 * Truncate to 3 characters
 * ```ts
 * const truncateTo3 = splice(3);
 * const s = truncateTo3("abcde");
 * console.log(s); // 'abc'
 * ```
 *
 * @example
 * Delete the second character
 * ```ts
 * const delete2ndChar = splice(1, 1);
 * const s = delete2ndChar("abc");
 * console.log(s); // 'ac'
 * ```
 *
 * @example
 * Replace last character with asterisk (`"*"`)
 * ```ts
 * const maskLastChar = splice(-1, 1, '*');
 * const s = maskLastChar("abc");
 * console.log(s); // 'ab*'
 * ```
 *
 * @return the spliced String
 */
export const splice =
  (start = 0, deleteCount?: number, replacement = "") =>
  (
    str: string,
    length = str.length,
    // internal variables:
    // normalize start index to align with Array.prototype.splice behavior
    normalizedStart = start < -length
      ? 0
      : start < 0
      ? mod(start, length)
      : start
  ): string => {
    return (
      str.slice(0, normalizedStart) +
      replacement +
      // normalize deleteCount to align with Array.prototype.splice behavior
      str.slice(
        normalizedStart + Math.max(deleteCount ?? length - normalizedStart, 0)
      )
    );
  };