背景:我有一个包含13000个人名记录的列表,其中有一些重复,我想找出相似的来进行手动去重。
对于像这样的数组:
["jeff","Jeff","mandy","king","queen"]
如何高效地获得以下内容:
[["jeff","Jeff"]]
解释:["jeff","Jeff"]
的Levenshtein距离为1(可以是变量,例如3)。/*
Working but a slow solution
*/
function extractSimilarNames(uniqueNames) {
let similarNamesGroup = [];
for (let i = 0; i < uniqueNames.length; i++) {
//compare with the rest of the array
const currentName = uniqueNames[i];
let suspiciousNames = [];
for (let j = i + 1; j < uniqueNames.length; j++) {
const matchingName = uniqueNames[j];
if (isInLevenshteinRange(currentName, matchingName, 1)) {
suspiciousNames.push(matchingName);
removeElementFromArray(uniqueNames, matchingName);
removeElementFromArray(uniqueNames, currentName);
i--;
j--;
}
}
if (suspiciousNames.length > 0) {
suspiciousNames.push(currentName);
}
}
return similarNamesGroup;
}
我希望通过Levenshtein距离来寻找相似度,不仅仅是大小写的相似度。
我已经找到了其中一个最快的Levenshtein实现,但是仍然需要35分钟才能得到13000个项目列表的结果。请参考talisman。
removeElementFromArray
函数正在影响你的性能,因为它改变了你正在遍历的数组。删除suspiciousNames.push(matchingName);
之后的4行内容,并使用console.time
和console.timeEnd
在较小的数组上进行性能测试。 - Aadit M Shah["Jeff", "eff", "effl"]
的预期输出是什么?此外,您只对Levenshtein距离为1感兴趣还是它可以是可变的? - גלעד ברקן