Skip to content

Instantly share code, notes, and snippets.

@paceaux
Last active February 26, 2024 18:15
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 paceaux/a1893fa76864b77aaee31d59e806e2e1 to your computer and use it in GitHub Desktop.
Save paceaux/a1893fa76864b77aaee31d59e806e2e1 to your computer and use it in GitHub Desktop.
String comparisons
/**
* @description calculates the levenshtein distance between words
* @param {string} str a string
* @param {string} str2 another string
* @returns {object} with properties 'steps' and 'transitions'
*/
function levenshtein(str, str2) {
if (typeof str !== 'string' || typeof str2 !== 'string') return;
let [shorter, longer] = [str, str2].sort((a, b) => a.length - b.length);
shorter = shorter.trim();
longer = longer.trim();
const sizeDiff = longer.length - shorter.length;
const truncatedLonger = longer.substring(0, shorter.length);
let steps = sizeDiff;
const transitions = [];
for (let i = 0; i < truncatedLonger.length; i++) {
const sChar = shorter.charAt(i);
const lChar = truncatedLonger.charAt(i);
const isStart = i === 0;
if (isStart) {
transitions.push(shorter);
}
if (sChar !== lChar) {
steps++;
const prevForm = transitions[transitions.length - 1];
const beforeReplace = isStart ? '' : prevForm.substring(0, i);
const afterReplace = prevForm.substring(i + 1);
const newForm = `${beforeReplace}${lChar}${afterReplace}`;
transitions.push(newForm);
}
}
if (sizeDiff) {
for (let i = 0; i < sizeDiff; i++) {
const lastTransition = transitions[transitions.length - 1];
const nextChar = longer.charAt(truncatedLonger.length + i);
const newForm = `${lastTransition}${nextChar}`;
transitions.push(newForm);
}
}
return {
steps,
transitions
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment