.NET[C#]LINQ查询List集合中所有重复的元素如何实现?(转载)
方案一
var query = lst.GroupBy(x=>x)
.Where(g=>g.Count()>1)
.Select(y=>y.Key)
.ToList();
如果还需要找出重复的元素个数:
var query = lst.GroupBy(x=>x)
.Where(g=>g.Count()>1)
.Select(y=> new { Element = y.Key, Counter = y.Count()})
.ToList();
如果需要返回结果为一个字典:
var query = lst.GroupBy(x=>x)
.Where(g=>g.Count()>1)
.ToDictionary(x=>x.Key,y=>y.Count());
方案二
查找List集合中任意一个重复的元素:
var anyDuplicate = enumerable.GroupBy(x => x.Key).Any(g => g.Count() > 1);
查找List集合中所有重复的元素:
var allUnique = enumerable.GroupBy(x => x.Key).All(g => g.Count() == 1);
方案三
使用 HashSet :
public static class Extensions
{
public static IEnumerable<TSource> GetDuplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IEqualityComparer<TKey> comparer)
{
var hash = new HashSet<TKey>(comparer);
return source.Where(item => !hash.Add(selector(item))).ToList();
}
public static IEnumerable<TSource> GetDuplicates<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
return source.GetDuplicates(x => x, comparer);
}
public static IEnumerable<TSource> GetDuplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
return source.GetDuplicates(selector, null);
}
public static IEnumerable<TSource> GetDuplicates<TSource>(this IEnumerable<TSource> source)
{
return source.GetDuplicates(x => x, null);
}
}
用法:
var hash = new HashSet<int>();
var duplicates = list.Where(i => !hash.Add(i));
方案四
public static class Extensions
{
public static IEnumerable<TSource> Duplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
var grouped = source.GroupBy(selector);
var moreThen1 = grouped.Where(i => i.IsMultiple());
return moreThen1.SelectMany(i => i);
}
public static IEnumerable<TSource> Duplicates<TSource, TKey>(this IEnumerable<TSource> source)
{
return source.Duplicates(i => i);
}
public static bool IsMultiple<T>(this IEnumerable<T> source)
{
var enumerator = source.GetEnumerator();
return enumerator.MoveNext() && enumerator.MoveNext();
}
}
用法:
var list = new[] {1,2,3,1,4,2};
var duplicateItems = list.Duplicates();
方案五
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public Person(int id, string name, string surname)
{
this.Id = id;
this.Name = name;
this.Surname = surname;
}
}
//静态扩展类
public static class Extention
{
public static IEnumerable<T> getMoreThanOnceRepeated<T>(this IEnumerable<T> extList, Func<T, object> groupProps) where T : class
{ //返回第二个以后面的重复的元素集合
return extList
.GroupBy(groupProps)
.SelectMany(z => z.Skip(1)); //跳过第一个重复的元素
}
public static IEnumerable<T> getAllRepeated<T>(this IEnumerable<T> extList, Func<T, object> groupProps) where T : class
{
//返回所有重复的元素集合
return extList
.GroupBy(groupProps)
.Where(z => z.Count() > 1) //Filter only the distinct one
.SelectMany(z => z);//All in where has to be retuned
}
}
//使用示例程序:
void DuplicateExample()
{
//填充数据
List<Person> PersonsLst = new List<Person>(){
new Person(1,"Ricardo","Figueiredo"), //第一个重复数据
new Person(2,"Ana","Figueiredo"),
new Person(3,"Ricardo","Figueiredo"),//第二个重复数据
new Person(4,"Margarida","Figueiredo"),
new Person(5,"Ricardo","Figueiredo")//第三个重复数据
};
Console.WriteLine("所有集合数据:");
PersonsLst.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
/* 输出:
所有集合数据:
1 -> Ricardo Figueiredo
2 -> Ana Figueiredo
3 -> Ricardo Figueiredo
4 -> Margarida Figueiredo
5 -> Ricardo Figueiredo
*/
Console.WriteLine("所有重复集合数据");
PersonsLst.getAllRepeated(z => new { z.Name, z.Surname })
.ToList()
.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
/* 输出:
所有重复集合数据
1 -> Ricardo Figueiredo
3 -> Ricardo Figueiredo
5 -> Ricardo Figueiredo
*/
Console.WriteLine("重复了一次以上的集合数据");
PersonsLst.getMoreThanOnceRepeated(z => new { z.Name, z.Surname })
.ToList()
.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
/* 输出:
重复了一次以上的集合数据
3 -> Ricardo Figueiredo
5 -> Ricardo Figueiredo
*/
}