Skip to content

Instantly share code, notes, and snippets.

@donbrae
Last active January 16, 2024 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donbrae/b42abccd5a7c4b1571c00943421e2a1f to your computer and use it in GitHub Desktop.
Save donbrae/b42abccd5a7c4b1571c00943421e2a1f to your computer and use it in GitHub Desktop.
JavaScript function which mimics PHP’s `similar_text()`.
// Source: ChatGPT 4
function similarText(first, second) {
// Check for null, undefined, or empty string inputs
if (first === null || second === null || typeof first === 'undefined' || typeof second === 'undefined' || first.trim().length === 0 || second.trim().length === 0) {
return { matchingCharacters: 0, similarityPercentage: 0 };
}
// Type coercion to ensure inputs are treated as strings
first += '';
second += '';
// Initialize variables for tracking positions and maximum match length
let pos1 = 0, pos2 = 0, max = 0,
firstLength = first.length, secondLength = second.length, p, q, l, sum;
// Iterate over each character of the first string
for (p = 0; p < firstLength; p++) {
// Iterate over each character of the second string
for (q = 0; q < secondLength; q++) {
// Count the length of the matching substring
for (l = 0; (p + l < firstLength) && (q + l < secondLength) && (first[p + l] === second[q + l]); l++);
// Update the maximum matching substring length and positions
if (l > max) {
max = l;
pos1 = p;
pos2 = q;
}
}
}
// Initialize sum with the maximum matching substring length
sum = max;
// Recursively find matching characters in the remaining substrings
if (sum) {
if (pos1 && pos2) {
sum += similarText(first.substr(0, pos2), second.substr(0, pos2)).matchingCharacters;
}
if ((pos1 + max < firstLength) && (pos2 + max < secondLength)) {
sum += similarText(first.substr(pos1 + max, firstLength - pos1 - max), second.substr(pos2 + max, secondLength - pos2 - max)).matchingCharacters;
}
}
// Calculate the similarity percentage
let longerLength = Math.max(firstLength, secondLength);
let percentage = (sum / longerLength) * 100;
// Return the total count of matching characters and the similarity percentage
return {matchingCharacters: sum, similarityPercentage: percentage};
}
@donbrae
Copy link
Author

donbrae commented Jan 16, 2024

For the use case of a simple (Scots) spellchecking tool I’m building, in terms of offering suggestions for words not in the dictionary (a JavaScript Set).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment