/** * Returns a number determining how similiar the second string is to the first (0-1) * @param first The first string * @param second The second string * @returns Similarity determiner */ export function stringSimilarity(first: string, second: string) { first = first.replace(/\s+/g, ''); second = second.replace(/\s+/g, ''); if (first === second) return 1; if (first.length < 2 || second.length < 2) return 0; let firstBigrams = new Map(); for (let i = 0; i < first.length - 1; i++) { const bigram = first.substring(i, i + 2); const count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) + 1 : 1; firstBigrams.set(bigram, count); } let intersectionSize = 0; for (let i = 0; i < second.length - 1; i++) { const bigram = second.substring(i, i + 2); const count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) : 0; if (count > 0) { firstBigrams.set(bigram, count - 1); intersectionSize++; } } return (2.0 * intersectionSize) / (first.length + second.length - 2); }