首页 / .NET / 正文

.NET[C#]LINQ查询List集合中所有重复的元素如何实现?

14263 发布于: 2018-01-18 读完约需15分钟

.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
        */
}

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: .NET[C#]C#中如何计算一个字符串中单词的个数?

下一篇: [MySQL]MySQL数据库中如何使用IF判断语句查询基于列值的结果?

本文永久链接码友网 » .NET[C#]LINQ查询List集合中所有重复的元素如何实现?

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册