找到差异的Lambda表达式

有以下数据

string[] data = { "a", "a", "b" }; 

我非常想找到重复项并得到这个结果:

 a 

我尝试了以下代码

 var a = data.Distinct().ToList(); var b = a.Except(a).ToList(); 

显然这不起作用,我可以看到上面发生了什么,但我不知道如何解决它。

当运行时没问题时,您可以使用

 var duplicates = data.Where(s => data.Count(t => t == s) > 1).Distinct().ToList(); 

好老O(n ^ n)=)

编辑:现在寻求更好的解决方案。 =)如果你定义一个新的扩展方法,如

 static class Extensions { public static IEnumerable Duplicates(this IEnumerable input) { HashSet hash = new HashSet(); foreach (T item in input) { if (!hash.Contains(item)) { hash.Add(item); } else { yield return item; } } } } 

您可以使用

 var duplicates = data.Duplicates().Distinct().ToArray(); 

使用group by stuff,这些方法的表现相当不错。 如果您正在处理大型数据集,那么唯一关注的是大量内存开销。

 from g in (from x in data group x by x) where g.Count() > 1 select g.Key; 

– 或者如果您更喜欢扩展方法

 data.GroupBy(x => x) .Where(x => x.Count() > 1) .Select(x => x.Key) 

其中Count() == 1这是你的不同项目,而Count() > 1是一个或多个重复项目。

由于LINQ有点懒惰,如果你不想重新计算你的计算,你可以这样做:

 var g = (from x in data group x by x).ToList(); // grouping result // duplicates from x in g where x.Count() > 1 select x.Key; // distinct from x in g where x.Count() == 1 select x.Key; 

创建分组时,将创建一组集。 假设它是具有O(1)插入的集合,则通过逼近的组的运行时间是O(n) 。 每项操作产生的成本有些高,但它应该等于接近线性的性能。

对数据进行排序,遍历它并记住最后一项。 当前项目与最后一项相同时,它是重复的。 这可以通过迭代或在O(n * log(n))时间内使用lambda表达式轻松实现。