• C# LINQ去重


    C# 使用自带的Distinct无法通过某一个属性值去重,因为使用自定义扩展方法去重。
    Net6版本出来了自带的DistinctBy属性。低版本没有。

    扩展代码

        public static class Extensions
        {
            public static IEnumerable<T> Distinct<T>(this IEnumerable<T> source, Func<T, T, bool> comparer) where T : class
                => source.Distinct(new DynamicEqualityComparer<T>(comparer));
    
            private sealed class DynamicEqualityComparer<T> : IEqualityComparer<T>
                where T : class
            {
                private readonly Func<T, T, bool> _func;
    
                public DynamicEqualityComparer(Func<T, T, bool> func)
                {
                    _func = func;
                }
                public bool Equals(T x, T y) => _func(x, y);
                public int GetHashCode(T obj) => 0;
            }
    
            public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
            {
                HashSet<TKey> seenKeys = new HashSet<TKey>();
                foreach (TSource element in source)
                {
                    if (seenKeys.Add(keySelector(element)))
                    {
                        yield return element;
                    }
                }
            }
        }
    

    实体类

            public class Person
            {
                public int Id { get; set; }
                public string Name { get; set; }
                public int Age { get; set; }
            }
    

    调用

            var list = new List<Person>();
    
            //第一种方式
            var list1 = list.GroupBy(d => d.Id).Select(d => d.FirstOrDefault()).ToList();
    
            //第二种方式
            var list2 = list.DistinctBy(d => d.Id).ToList();
    
            //第三种方式
            var list3 = list.Distinct((a, b) => a.Age == b.Age && a.Name == b.Name).ToList();
    

    性能比较

    //数据量小基本没有性能问题,数据量大建议使用第三种。
    var list = new List<Person>();
    for (int i = 0; i < 1000000; i++)
    {
        list.Add(new Person() { Age = 18, Name = "jeffcky" });
    }
    
    var time1 = Time(() =>
    {
        list.GroupBy(d => new { d.Age, d.Name })
            .Select(d => d.FirstOrDefault())
            .ToList();
    });
    Console.WriteLine($"分组耗时:{time1}");
    
    var time2 = Time(() =>
    {
        list.Distinct(d => new { d.Age, d.Name }).ToList();
    });
    Console.WriteLine($"HashSet耗时:{time2}");
    
    var time3 = Time(() =>
    {
        list.Distinct((a, b) => a.Age == b.Age && a.Name == b.Name).ToList();
    });
    Console.WriteLine($"委托耗时:{time3}");
    
    
    static long Time(Action action)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        action();
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }
    
  • 相关阅读:
    毕业设计过程复盘
    关于理想
    Python之网络模型与图形绘制工具networkx
    Python之Numpy:二元函数绘制/三维数据可视化/3D
    JavaScript之参数传递方式
    Python之滑动窗口
    [转] JavaScript 原型理解与创建对象应用
    [转] JavaScript 和事件
    [转] 三步将你的 React Native 项目运行在 Web 浏览器上面
    [转] Webpack 入门指迷
  • 原文地址:https://www.cnblogs.com/RainFate/p/16769521.html
Copyright © 2020-2023  润新知