getJaro method

double getJaro(
  1. String other, [
  2. bool caseSensitive = true
])

The Jaro distance is a measure of edit distance between two strings

its inverse, called the Jaro similarity, is a measure of two String's similarity:

the higher the value, the more similar the strings are.

Example

String t1 = 'esentis';
String t2 = 'esen';
print(t1.getJaro(t2)); // prints 0.8571428571428571

Implementation

double getJaro(String other, [bool caseSensitive = true]) {
  if (other == this) {
    return 1;
  }

  if (other.isBlank || isBlank) {
    return 0;
  }

  if (!caseSensitive) {
    return toLowerCase().getJaro(other.toLowerCase());
  }
  int len1 = length;
  int len2 = other.length;

  // Maximum allowed matching distance
  int matchDistance = (max(len1, len2) ~/ 2) - 1;

  // Arrays to track character matches
  List<bool> s1Matches = List.filled(len1, false);
  List<bool> s2Matches = List.filled(len2, false);

  int commonMatches = 0;
  for (int i = 0; i < len1; i++) {
    int start = max(0, i - matchDistance);
    int end = min(len2 - 1, i + matchDistance);

    for (int j = start; j <= end; j++) {
      if (!s2Matches[j] && this[i] == other[j]) {
        s1Matches[i] = true;
        s2Matches[j] = true;
        commonMatches++;
        break;
      }
    }
  }

  if (commonMatches == 0) {
    return 0.0;
  }

  // Calculate transpositions
  int transpositions = 0;
  int k = 0;
  for (int i = 0; i < len1; i++) {
    if (s1Matches[i]) {
      while (!s2Matches[k]) {
        k++;
      }
      if (this[i] != other[k]) {
        transpositions++;
      }
      k++;
    }
  }

  return (commonMatches.toDouble() / len1 + commonMatches.toDouble() / len2 + (commonMatches - transpositions).toDouble() / commonMatches) / 3.0;
}