<commit_before>/**
 * inclusive
 * */
export function isBetween<A extends number | string>(
  a: A,
  b: A,
  c: A,
): boolean {
  return a <= b && b <= c;
}

export enum CompareResult {
  Smaller = -1,
  Equal = 0,
  Larger = 1,
}

export function compare<A extends number | string>(a: A, b: A): CompareResult {
  return a < b
    ? CompareResult.Smaller
    : a > b
    ? CompareResult.Larger
    : CompareResult.Equal;
}

export function compare_by_keys<T extends object, K extends keyof T>(
  keys: K[],
) {
  return <T extends Record<K, number | string>>(a: T, b: T): CompareResult => {
    let cmp = 0;
    for (const key of keys) {
      cmp = compare(a[key], b[key]);
      if (cmp !== 0) {
        break;
      }
    }
    return cmp;
  };
}
<commit_msg>enhanced compare_by_keys to allow descending compare<commit_after>/**
 * inclusive
 * */
export function isBetween<A extends number | string>(
  a: A,
  b: A,
  c: A,
): boolean {
  return a <= b && b <= c;
}

export enum CompareResult {
  Smaller = -1,
  Equal = 0,
  Larger = 1,
}

export function compare<A extends number | string>(a: A, b: A): CompareResult {
  return a < b
    ? CompareResult.Smaller
    : a > b
    ? CompareResult.Larger
    : CompareResult.Equal;
}

export type SortKey<K> = {
  key: K;
  order: 'asc' | 'desc';
};

export function compare_by_keys<T extends object, K extends keyof T>(
  _keys: Array<K | SortKey<K>>,
) {
  const keys: Array<SortKey<K>> = _keys.map(key => {
    if (typeof key === 'object') {
      return key;
    }
    return { key, order: 'asc' };
  });
  return <T extends Record<K, number | string>>(a: T, b: T): CompareResult => {
    for (const { key, order } of keys) {
      const cmp = compare(a[key], b[key]);
      if (cmp !== 0) {
        return order === 'desc' ? -cmp : cmp;
      }
    }
    return 0;
  };
}

{'fraction_non_alphanumeric': 0.15510649918077554, 'fraction_numerical': 0.005461496450027308, 'mean_word_length': 2.6421471172962225, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4389805', 'n_tokens_mistral': 687, 'n_tokens_neox': 656, 'n_words': 201}