C# Distinct方法的使用笔记

引自:http://blog.csdn.net/shaopengfei/article/details/36426763

从C# 3.0开始提供了Distinct方法,这对于集合的使用有了更为丰富的方法,经过在网上搜索相应的资源,发现有关这方面的写的好的文章还是不少的。而且为了扩展Linq的使用不方便的地方,有一些办法非常有效。由于本人工作中的需要,有一些功能暂时没有用到那么深入,现在只把最简单的一些功能分享出来,整理出来。

  1. 简单一维集合的使用:

    [csharp] view plaincopy

    1. List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };
    2. List<string> names = new List<string> { "wang", "li", "zhang", "li", "wang", "chen", "he", "wang" };
    3. IEnumerable<int> distinctAges = ages.Distinct();
    4. Console.WriteLine("Distinct ages:");
    5. foreach (int age in distinctAges)
    6. {
    7. Console.WriteLine(age);
    8. }
    9. var distinctNames = names.Distinct();
    10. Console.WriteLine("\nDistinct names:");
    11. foreach (string name in distinctNames)
    12. {
    13. Console.WriteLine(name);
    14. }
    • 在这段代码中,是最简单的Distinct()方法的使用。使用了集合接口IEnumerable,以及隐式类型var,至于这两种用法有什么区别,没有研究出来。
    • 但是如果象下面这样的代码,是错误的!

    [csharp] view plaincopy

    1. List<int> disAge = ages.Distinct();
    • 正确的方法应该是:

    [csharp] view plaincopy

    1. List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };
    2. List<int> disAge = ages.Distinct().ToList();
    3. foreach (int a in disAge)
    4. Console.WriteLine(a);
    • 也就是说Distinct()方法的返回集合类型是一个接口,不是具体的集合,所以需要用一个ToList()。
  2. 自定义类的使用:

    • 首先我们看MSDN上给出的例子,先定义一个产品类:

    [csharp] view plaincopy

    1. public class Product : IEquatable<Product>
    2. {
    3. public string Name { get; set; }
    4. public int Code { get; set; }
    5. public bool Equals(Product other)
    6. {
    7. //Check whether the compared object is null.
    8. if (Object.ReferenceEquals(other, null)) return false;
    9. //Check whether the compared object references the same data.
    10. if (Object.ReferenceEquals(this, other)) return true;
    11. //Check whether the products‘ properties are equal.
    12. return Code.Equals(other.Code) && Name.Equals(other.Name);
    13. }
    14. // If Equals() returns true for a pair of objects
    15. // then GetHashCode() must return the same value for these objects.
    16. public override int GetHashCode()
    17. {
    18. //Get hash code for the Name field if it is not null.
    19. int hashProductName = Name == null ? 0 : Name.GetHashCode();
    20. //Get hash code for the Code field.
    21. int hashProductCode = Code.GetHashCode();
    22. //Calculate the hash code for the product.
    23. return hashProductName ^ hashProductCode;
    24. }
    25. }
    • 在主函数里,是这样用的:

    [csharp] view plaincopy

    1. static void Main(string[] args)
    2. {
    3. Product[] products =
    4. {
    5. new Product { Name = "apple", Code = 9 },
    6. new Product { Name = "orange", Code = 4 },
    7. new Product { Name = "apple", Code = 9 },
    8. new Product { Name = "lemon", Code = 12 }
    9. };
    10. //Exclude duplicates.
    11. IEnumerable<Product> noduplicates =
    12. products.Distinct();
    13. foreach (var product in noduplicates)
    14. Console.WriteLine(product.Name + " " + product.Code);
    15. }
    • 这样的输出是:

    [csharp] view plaincopy

    1. /*
    2. This code produces the following output:
    3. apple 9
    4. orange 4
    5. lemon 12
    6. */
    • 但是现在的问题是,如果我们把主函数里改成这样:

    [csharp] view plaincopy

    1. static void Main(string[] args)
    2. {
    3. Product[] products =
    4. {
    5. new Product { Name = "Smallapple", Code = 9 },
    6. new Product { Name = "orange", Code = 4 },
    7. new Product { Name = "Bigapple", Code = 9 },
    8. new Product { Name = "lemon", Code = 12 }
    9. };
    10. //Exclude duplicates.
    11. IEnumerable<Product> noduplicates =
    12. products.Distinct();
    13. foreach (var product in noduplicates)
    14. Console.WriteLine(product.Name + " " + product.Code);
    15. }
    • 这样的输出是:

    [csharp] view plaincopy

    1. /*
    2. This code produces the following output:
    3. Smallapple 9
    4. orange 4
    5. Bigapple 9
    6. lemon 12
    7. */
    • 我们的问题是,如果想按Code来索引,想找出Code唯一的这些成员,那么这里就需要重新定义一个对Code比较的类,或者再扩展成泛型类,但是这样非常繁琐。
  3. 博客鹤冲天的改进办法(以下均转自这个博客)

    • 首先,创建一个通用比较的类,实现IEqualityComparer<T>接口:

    [csharp] view plaincopy

    1. public class CommonEqualityComparer<T, V> : IEqualityComparer<T>
    2. {
    3. private Func<T, V> keySelector;
    4. public CommonEqualityComparer(Func<T, V> keySelector)
    5. {
    6. this.keySelector = keySelector;
    7. }
    8. public bool Equals(T x, T y)
    9. {
    10. return EqualityComparer<V>.Default.Equals(keySelector(x), keySelector(y));
    11. }
    12. public int GetHashCode(T obj)
    13. {
    14. return EqualityComparer<V>.Default.GetHashCode(keySelector(obj));
    15. }
    16. }
    • 借助上面这个类,Distinct扩展方法就可以这样写:

    [csharp] view plaincopy

    1. public static class DistinctExtensions
    2. {
    3. public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector)
    4. {
    5. return source.Distinct(new CommonEqualityComparer<T, V>(keySelector));
    6. }
    7. }
    • 下面的使用就很简单了:

    [csharp] view plaincopy

    1. Product[] products =
    2. {
    3. new Product { Name = "Smallapple", Code = 9 },
    4. new Product { Name = "orange", Code = 4 },
    5. new Product { Name = "Bigapple", Code = 9 },
    6. new Product { Name = "lemon", Code = 12 }
    7. };
    8. var p1 = products.Distinct(p => p.Code);
    9. foreach (Product pro in p1)
    10. Console.WriteLine(pro.Name + "," + pro.Code);
    11. var p2 = products.Distinct(p => p.Name);
    12. foreach (Product pro in p2)
    13. Console.WriteLine(pro.Name + "," + pro.Code);
    • 可以看到,加上Linq表达式,可以方便的对自定义类的任意字段进行Distinct的处理。
时间: 2024-08-04 20:01:55

C# Distinct方法的使用笔记的相关文章

黑马程序员---Objective-C基础学习---类、对象、方法相关知识笔记

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 类.对象.方法相关知识笔记 Objective-C相对于C语言有了面向对象的特性,但是ObjC又没有其他面向对象语言那么多语法特性,ObjC本身对面向对象进行了精简.下面是一些相关知识笔记. 类定义 成员变量 方法和属性 self关键字 类定义 在C#.Java等其他高级语言中定义一个类是相当简单点的,直接一个关键字class加一对大括号基本就完成了,但是在ObjC中类的定义相对变化比较大.现

使用Linq中的Distinct方法对序列进行去重操作

使用Linq提供的扩展方法Distinct可以去除序列中的重复元素. 该方法具有以下两种重载形式: (1)public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source) (重载1) 通过使用默认的相等比较器对值进行比较并返回序列中的非重复元素. (2)publicstatic IQueryable<TSource> Distinct<TSour

iOS开发中的那些的约定俗成(1)————《编写高质量iOS与OS X代码的52个有效方法》读书笔记(第一章)

iOS开发中的那些的约定俗成(1) ----<编写高质量iOS与OS X代码的52个有效方法>读书笔记(第一章) 前言 "我要成为一个高产的开发人员.""想要混的好,就得多努力." 写这些东西是因为毕竟看了书,但是看书看过去之后,也许印象不是很深刻,有些东西现在也理解不了,那我就把我理解的,现在就可以用到的东西,简单的写出来就好,让自己今后看到就能明白其中的意思. 还有就是锻炼一下表达,编辑能力,慢慢的提升自己,随时随地的都要有一个锻炼的心. 最后当然就

【C#】详解使用Enumerable.Distinct方法去重

Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组.集合中的重复元素,还可以自定义去重的规则. 有两个重载方法: // // 摘要: // 通过使用默认的相等比较器对值进行比较返回序列中的非重复元素. // // 参数: // source: // 要从中移除重复元素的序列. // // 类型参数: // TSource: // source 中的元素的类型. // // 返回结果: // 一个 Syste

如何很好的使用Linq的Distinct方法

Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1" Person3: Id=2, Name="Test2" 以上list如果直接使用distinct方法进行过滤,仍然返回3条数据,而需要的结果是2条数据.下面给出解这个问题的方法: 方法1: Distinct 方法中使用的相等比较器.这个比较器需要重写Equals和GetHashCode方法,个人不推荐,感觉较麻烦,需要些多余的类,并且用

扩展Linq的Distinct方法动态根据条件进行筛选

声明为了方便自己查看所以引用 原文地址:http://www.cnblogs.com/A_ming/archive/2013/05/24/3097062.html Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1" Person3: Id=2, Name="Test2" 以上list如果直接使用distinct方法进行过滤,仍然返回3条数据,而需要的结果是2条数据.下面给出解这个问题的方

DISTINCT 方法用于返回唯一不同的值 。

例如: $Model->distinct(true)->field('name')->select(); 生成的SQL语句是: SELECT DISTINCT name FROM think_user distinct方法的参数是一个布尔值. 大理石平台厂家 原文地址:https://www.cnblogs.com/furuihua/p/11804375.html

《麦肯锡方法》读书笔记

1. 建立解决方案 以事实为基础 严格的结构化 以假设为导向 2. MECE “相互独立,完全穷尽”.解决方案的内容清单是相互独立的,没有重叠,因为重叠意味着作者思路含混不清而导致读者的困惑.然后必须保证它同时还囊括与这一问题有关的所有内容或事项--“完全穷尽”. 3. 一份满意的麦肯锡问题清单所含的最顶层的一级内容不会少于2个,也不会多于5个,最好是3个. 4.定义最初的假设 假设仅仅是有待证明或驳斥的理论.它不是答案.如果你的最初假设是正确的,那么,沿着这条路走上几个月,它就会成为你进行情况

System.Linq Distinct 方法使用

首先看到Distinct 肯定会想当然的直接.Distinct() 这样调用. 需要知道这里的Distinct 是以对象为单位来去重的.当你Select new 映射的时候就算属性值相同也不会进行去重. 单列的使用这里就略过使用了 多列的使用(比如我需要去重KeyValuePairModel 这个对象 ): public class KeyValuePairModel { public string Name { get; set; } public string Code { get; set