• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

C# 数组Linq 的三种去重方式Distinct

武飞扬头像
mark10!
帮助1

前言

首先给出我们需要用到的对象,如下:

  1.  
    public class Person
  2.  
    {
  3.  
    public string Name { get; set; }
  4.  
    public int Age { get; set; }
  5.  
    }

接下来我们添加100万条数据到集合中,如下:

  1.  
    var list = new List<Person>();
  2.  
    for (int i = 0; i < 1000000; i )
  3.  
    {
  4.  
    list.Add(new Person() { Age = 18, Name = "迷恋自留地" });
  5.  
    }
  6.  
    for (int i = 0; i < 1000; i )
  7.  
    {
  8.  
    list.Add(new Person() { Age = 19, Name = "迷恋自留地" });
  9.  
    }

第一种分组去重

年龄和名称进行分组,然后取第一条即可达到去重,如下:

  1.  
    var list1 = list.GroupBy(d => new { d.Age, d.Name })
  2.  
    .Select(d => d.FirstOrDefault())
  3.  
    .ToList();

第二种 HashSet去重 (扩展方法)

  1.  
    public static IEnumerable<TSource> Distinct<TSource, TKey>(
  2.  
    this IEnumerable<TSource> source,
  3.  
    Func<TSource, TKey> keySelector)
  4.  
    {
  5.  
    var hashSet = new HashSet<TKey>();
  6.  
     
  7.  
    foreach (TSource element in source)
  8.  
    {
  9.  
    if (hashSet.Add(keySelector(element)))
  10.  
    {
  11.  
    yield return element;
  12.  
    }
  13.  
    }
  14.  
    }

述扩展方法即可去重,如下:

 var  list2 = list.Distinct(d => new { d.Age, d.Name }).ToList();

第三种 IEqualityComparer去重 (扩展方法)

  1.  
    public static class Extensions
  2.  
    {
  3.  
    public static IEnumerable<T> Distinct<T>(
  4.  
    this IEnumerable<T> source, Func<T, T, bool> comparer)
  5.  
    where T : class
  6.  
    => source.Distinct(new DynamicEqualityComparer<T>(comparer));
  7.  
     
  8.  
    private sealed class DynamicEqualityComparer<T> : IEqualityComparer<T>
  9.  
    where T : class
  10.  
    {
  11.  
    private readonly Func<T, T, bool> _func;
  12.  
     
  13.  
    public DynamicEqualityComparer(Func<T, T, bool> func)
  14.  
    {
  15.  
    _func = func;
  16.  
    }
  17.  
     
  18.  
    public bool Equals(T x, T y) => _func(x, y);
  19.  
     
  20.  
    public int GetHashCode(T obj) => 0;
  21.  
    }
  22.  
    }
学新通

最终通过指定属性进行比较即可去重,如下:

list = list.Distinct((a, b) => a.Age == b.Age && a.Name == b.Name).ToList();

性能比较

我们来分析其耗时情况,如下:

  1.  
    var list = new List<Person>();
  2.  
    for (int i = 0; i < 1000000; i )
  3.  
    {
  4.  
        list.Add(new Person() { Age = 18, Name = "jeffcky" });
  5.  
    }
  6.  
     
  7.  
    var time1 = Time(() =>
  8.  
    {
  9.  
        list.GroupBy(d => new { d.Age, d.Name })
  10.  
            .Select(d => d.FirstOrDefault())
  11.  
            .ToList();
  12.  
    });
  13.  
    Console.WriteLine($"分组耗时:{time1}");
  14.  
     
  15.  
    var time2 = Time(() =>
  16.  
    {
  17.  
        list.Distinct(d => new { d.Age, d.Name }).ToList();
  18.  
    });
  19.  
    Console.WriteLine($"HashSet耗时:{time2}");
  20.  
     
  21.  
    var time3 = Time(() =>
  22.  
    {
  23.  
        list.Distinct((a, b) => a.Age == b.Age && a.Name == b.Name).ToList();
  24.  
    });
  25.  
    Console.WriteLine($"委托耗时:{time3}");
  26.  
     
  27.  
     
  28.  
    static long Time(Action action)
  29.  
    {
  30.  
        var stopwatch = new Stopwatch();
  31.  
        stopwatch.Start();
  32.  
        action();
  33.  
        stopwatch.Stop();
  34.  
        return stopwatch.ElapsedMilliseconds;
  35.  
    }
学新通

LISP 复制 全屏

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcabib
系列文章
更多 icon
同类精品
更多 icon
继续加载