C#含重复元素List比较:获取双方不匹配元素的方案问询
处理含重复元素的C# List比较,返回所有不匹配元素
需求:对两个包含重复元素的C# List进行比较,返回双方所有不匹配的元素(即考虑元素出现次数的差异,将一方比另一方多的元素全部返回)。
示例场景1
List<string> listA = new List<string> { "L1", "AB", "L1" }; List<string> listB = new List<string> { "L1", "AB" };
预期结果:
List<string> result = { "L1" };
示例场景2
List<string> listA = new List<string> { "L1" }; List<string> listB = new List<string> { "L1", "AB", "L1"};
预期结果:
List<string> result = { "AB", "L1" };
尝试过的无效方法
以下方法均未得到预期结果,原因是标准LINQ方法基于集合语义,自动去重且不考虑元素出现次数:
// 仅返回listA中不存在于listB的元素,不考虑数量差异 List<string> result = listA.Except(listB).ToList(); // 仅返回只存在于单一列表的元素,忽略数量差异 List<string> result = listA.Concat(listB).Where(w => !(listA.Contains(w) && listB.Contains(w))).ToList(); // 同上,Union已去重,仍忽略数量差异 List<string> result = listA.Union(listB).Where(w => !(listA.Contains(w) && listB.Contains(w))).ToList(); // 仅返回只存在于单一列表的元素,忽略数量差异 List<string> result = listA.Union(listB).Except(listA.Intersect(listB)).ToList();
正确实现方案
核心思路是统计每个元素在两个列表中的出现次数,然后计算次数差值,将超出对方数量的元素按次数添加到结果中:
using System; using System.Collections.Generic; using System.Linq; public static class ListExtensions { public static List<T> GetMismatchedElements<T>(this List<T> listA, List<T> listB) where T : notnull { // 统计listA中各元素的出现次数 var countA = listA.GroupBy(item => item) .ToDictionary(group => group.Key, group => group.Count()); // 统计listB中各元素的出现次数 var countB = listB.GroupBy(item => item) .ToDictionary(group => group.Key, group => group.Count()); var mismatched = new List<T>(); // 处理listA中比listB多的元素 foreach (var (item, count) in countA) { countB.TryGetValue(item, out var bCount); int excess = count - bCount; if (excess > 0) { mismatched.AddRange(Enumerable.Repeat(item, excess)); } } // 处理listB中比listA多的元素 foreach (var (item, count) in countB) { countA.TryGetValue(item, out var aCount); int excess = count - aCount; if (excess > 0) { mismatched.AddRange(Enumerable.Repeat(item, excess)); } } return mismatched; } } // 测试代码 public class Program { public static void Main() { // 示例1 var listA1 = new List<string> { "L1", "AB", "L1" }; var listB1 = new List<string> { "L1", "AB" }; var result1 = listA1.GetMismatchedElements(listB1); // 输出结果: ["L1"] // 示例2 var listA2 = new List<string> { "L1" }; var listB2 = new List<string> { "L1", "AB", "L1" }; var result2 = listA2.GetMismatchedElements(listB2); // 输出结果: ["AB", "L1"] } }
代码说明
- 用
GroupBy和ToDictionary统计每个元素在两个列表中的出现次数; - 遍历两个统计字典,计算当前列表元素数量与对方的差值;
- 将差值为正的元素按重复次数添加到结果列表,确保保留所有数量不匹配的元素。
内容的提问来源于stack exchange,提问作者user1635003
相关产品推荐
相关产品推荐

