All files / text / unstable_longest_common_prefix.ts

100.00% Branches 13/13
100.00% Lines 21/21
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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x5
x110
x110
x112
x110
x114
x110
x201
x110
 
x118
x110
 
x313
x313
x313
 
x313
x214
x461
x461
 
 
x930
 
x313
x110












































// Copyright 2018-2025 the Deno authors. MIT license.
// This module is browser compatible.

/**
 * Gets the longest common prefix of an array of strings.
 *
 * @experimental **UNSTABLE**: New API, yet to be vetted.
 *
 * @param strs The array of strings to find the common prefix for.
 * @returns The longest common prefix.
 *
 * @example Usage
 * ```ts
 * import { longestCommonPrefix } from "@std/text/unstable-longest-common-prefix";
 * import { assertEquals } from "@std/assert";
 *
 * assertEquals(longestCommonPrefix(["flower", "flow", "flight"]), "fl");
 * ```
 */
export function longestCommonPrefix(strs: ArrayLike<string>): string {
  switch (strs.length) {
    case 0:
      return "";
    case 1:
      return strs[0]!;
    case 2:
      break;
    default:
      // sorting lexicographically ensures we only need to compare the first and last strings
      strs = Array.from(strs).sort();
  }

  const a = strs[0]!;
  const b = strs[strs.length - 1]!;
  const maxLength = Math.min(a.length, b.length);

  let end = 0;
  for (; end < maxLength; ++end) {
    if (a[end] !== b[end]) break;
  }

  // strip lone surrogates at end (unless both prefixes end with the same lone surrogate)
  if (end && [a, b].some((s) => s.codePointAt(end - 1)! > 0xffff)) --end;

  return a.slice(0, end);
}