C#中如何实现List内Customer类Name属性的两两模糊字符串对比
实现方案
你当前代码仅实现自身对比的核心原因是只使用了单层循环遍历集合,每次调用模糊对比方法时传入的两个参数都是当前遍历到的同一个实例的Name属性。要实现列表内所有元素两两交叉对比,调整为双层遍历逻辑即可,以下是修改后的代码:
static void Main(string[] args) { var customers = ReadXls(); // 对比参数全局只创建一次即可,避免重复实例化消耗性能 List<FuzzyStringComparisonOptions> options = new List<FuzzyStringComparisonOptions> { FuzzyStringComparisonOptions.UseOverlapCoefficient, FuzzyStringComparisonOptions.UseLongestCommonSubsequence, FuzzyStringComparisonOptions.UseLongestCommonSubstring }; FuzzyStringComparisonTolerance tolerance = FuzzyStringComparisonTolerance.Normal; // 外层遍历:拿到每个作为对比源的客户 foreach (var sourceCustomer in customers) { Console.WriteLine($"===== 当前对比源客户:{sourceCustomer.Name} ====="); // 内层遍历:拿到所有待对比的客户 foreach (var targetCustomer in customers) { // 跳过和自身的对比 if (sourceCustomer == targetCustomer) continue; // 可选:如果两个姓名都是空值也跳过对比 if (string.IsNullOrWhiteSpace(sourceCustomer.Name) && string.IsNullOrWhiteSpace(targetCustomer.Name)) continue; bool isMatch = sourceCustomer.Name.ApproximatelyEquals(targetCustomer.Name, options, tolerance); double hamming = sourceCustomer.Name.HammingDistance(targetCustomer.Name); double jaccard = sourceCustomer.Name.JaccardDistance(targetCustomer.Name); double jaro = sourceCustomer.Name.JaroDistance(targetCustomer.Name); double lev = sourceCustomer.Name.LevenshteinDistance(targetCustomer.Name); Console.WriteLine($"对比目标客户:{targetCustomer.Name},匹配结果:{isMatch},汉明距离:{hamming},杰卡德距离:{jaccard},Jaro距离:{jaro},莱文斯坦距离:{lev}"); if (isMatch) { Console.WriteLine($">> 匹配成功:{sourceCustomer.Name} 与 {targetCustomer.Name} 符合模糊匹配规则"); } } Console.WriteLine($"源客户信息:姓名:{sourceCustomer.Name}\n 电话:{sourceCustomer.Phone}\n联系人:{sourceCustomer.Contact}\n邮箱:{sourceCustomer.Email}\n"); } }
如果需要优化重复对比(比如A和B对比后不需要再执行B和A的对比,减少一半计算量),可以改用索引遍历的方式:
static void Main(string[] args) { var customers = ReadXls(); List<FuzzyStringComparisonOptions> options = new List<FuzzyStringComparisonOptions> { FuzzyStringComparisonOptions.UseOverlapCoefficient, FuzzyStringComparisonOptions.UseLongestCommonSubsequence, FuzzyStringComparisonOptions.UseLongestCommonSubstring }; FuzzyStringComparisonTolerance tolerance = FuzzyStringComparisonTolerance.Normal; for (int i = 0; i < customers.Count; i++) { var sourceCustomer = customers[i]; Console.WriteLine($"===== 当前对比源客户:{sourceCustomer.Name} ====="); // 内层从i+1开始遍历,只和后面的元素对比,避免重复计算 for (int j = i + 1; j < customers.Count; j++) { var targetCustomer = customers[j]; if (string.IsNullOrWhiteSpace(sourceCustomer.Name) && string.IsNullOrWhiteSpace(targetCustomer.Name)) continue; bool isMatch = sourceCustomer.Name.ApproximatelyEquals(targetCustomer.Name, options, tolerance); double hamming = sourceCustomer.Name.HammingDistance(targetCustomer.Name); double jaccard = sourceCustomer.Name.JaccardDistance(targetCustomer.Name); double jaro = sourceCustomer.Name.JaroDistance(targetCustomer.Name); double lev = sourceCustomer.Name.LevenshteinDistance(targetCustomer.Name); Console.WriteLine($"对比目标客户:{targetCustomer.Name},匹配结果:{isMatch},汉明距离:{hamming},杰卡德距离:{jaccard},Jaro距离:{jaro},莱文斯坦距离:{lev}"); if (isMatch) { Console.WriteLine($">> 匹配成功:{sourceCustomer.Name} 与 {targetCustomer.Name} 符合模糊匹配规则"); } } Console.WriteLine($"源客户信息:姓名:{sourceCustomer.Name}\n 电话:{sourceCustomer.Phone}\n联系人:{sourceCustomer.Contact}\n邮箱:{sourceCustomer.Email}\n"); } }
内容的提问来源于stack exchange,提问作者rafael lopes
相关产品推荐
相关产品推荐

