All files deepSort.ts

79.17% Statements 38/48
69.23% Branches 18/26
77.78% Functions 7/9
87.18% Lines 34/39

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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 831x                 1x 1x 1x         20x 2x 2x     8x 8x 8x 4x 4x       4x     12x         18x           18x             1x 15x 15x 13x 5x 5x 5x   5x 2x   10x   2x 5x 5x     2x     3x 3x 9x   20x              
import {
  isString,
  isNumber,
  isFunction,
  isPromise,
  isBoolean,
  isObject,
  isArray,
} from './guards';
import { pipe } from './pipe';
import { sortBy } from './sortBy';
import { map } from './map';
 
export type SortFunction<T> = (a: T, b: T) => number;
 
function anyToString(data: unknown): string {
  if (isObject(data)) {
    const keys = Object.keys(data);
    return pipe(
      keys,
      map(key => {
        const value = data[key];
        Iif (isString(value)) return `${key}:${value}`;
        if (isNumber(value)) return `${key}:${value}`;
        Iif (isBoolean(value)) return `${key}:${String(value)}`;
        Iif (isObject(value)) {
          return `${key}:${anyToString(value)}`;
        }
 
        return `${key}:${String(value)}`;
      }),
      sortBy(c => {
        return c;
      })
    ).join(':');
  }
 
  Iif (isArray(data)) {
    return pipe(
      data.map(d => anyToString(d)),
      sortBy(c => c)
    ).join(':');
  }
  return String(data);
}
 
/**
 * Recursivly sort arrays and objects.
 * @param value - anything
 */
export function deepSort<T>(value: T): T {
  const v = value as unknown;
  if (isString(v)) return value;
  if (isNumber(v)) return value;
  Iif (isFunction(v)) return value;
  Iif (isPromise(v)) return value;
  Iif (isBoolean(v)) return value;
 
  if (isObject(v)) {
    const keys = pipe(
      Object.keys(value),
      sortBy(c => c)
    );
    const obj = {} as Record<string, unknown>;
    for (const k of keys) {
      obj[k] = deepSort(v[k]);
    }
 
    return obj as T;
  }
 
  Eif (isArray(v)) {
    return (pipe(
      v.map(q => deepSort(q)),
      sortBy(c => {
        return anyToString(c);
      })
    ) as unknown) as T;
  }
 
  return value;
}