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

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

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

    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,至于这两种用法有什么区别,没有研究出来。
    • 但是如果象下面这样的代码,是错误的!
    1. List<int> disAge = ages.Distinct();
    • 正确的方法应该是:
    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上给出的例子,先定义一个产品类:
    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. }
    • 在主函数里,是这样用的:
    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. }
    • 这样的输出是:
    1. /*
    2. This code produces the following output:
    3. apple 9
    4. orange 4
    5. lemon 12
    6. */
    • 但是现在的问题是,如果我们把主函数里改成这样:
    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. }
    • 这样的输出是:
    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>接口:
    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扩展方法就可以这样写:
    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. }
    • 下面的使用就很简单了:
    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的处理。

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

  1. 重写类的Equals以及重写Linq下的Distinct方法

    当自定义一个类的时候,如果需要用到对比的功能,可以自己重写Equals方法,最整洁的方法是重写GetHashCode()方法. 但是,这个方法只适用于对象自身的对比(如if(a==b))以及字典下的C ...

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

    Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1" Person3: Id=2, Name=&quo ...

  3. Linq的Distinct方法的扩展

    原文地址:如何很好的使用Linq的Distinct方法 Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1&qu ...

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

    Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组.集合中的重复元素,还可以自定义去重的规则. 有两个重载方法 ...

  5. 如何使用Linq或EF来对数据去重——Distinct方法详解

    刚开始接触LINQ时使用distinct去重时和大家一样遇到了一些麻烦,很感谢 http://www.cnblogs.com/A_ming/archive/2013/05/24/3097062.htm ...

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

    声明为了方便自己查看所以引用 原文地址:http://www.cnblogs.com/A_ming/archive/2013/05/24/3097062.html Person1: Id=1, Nam ...

  7. Linq Enumerable.Distinct方法去重

    Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组.集合中的重复元素,还可以自定义去重的规则. 有两个重载方法 ...

  8. 【转载】C#中通过Distinct方法对List集合进行去重

    在C#的List集合对象中,可以使用Distinct方法来对List集合元素进行去重,如果list集合内部元素为值类型,则Distinct方法根据值类型是否相等来判断去重,如果List集合内部元素为引 ...

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

    DISTINCT 方法用于返回唯一不同的值 . 例如: $Model->distinct(true)->field('name')->select(); 生成的SQL语句是: SEL ...

随机推荐

  1. listview禁止双击一条之后选中复选框按钮的方法

    this.listViewUsers.SelectedItems[0].Checked = !this.listViewUsers.SelectedItems[0].Checked;

  2. poj3687

    Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9028   Accepted: 2444 De ...

  3. Objective-C中的@property

    1:@property 是什么? 在Objective-C中,@property 是声明属性的语法,它可以快速方便的为实例变量创建getter/setter方法. 2:@property 的本质? @ ...

  4. Js面向对象和数据类型内存分配(转)

    一 Js基本数据类型以及内存情况 1 Undefined Undefined类型只有一个值undefined,在使用了声明但未初始化的变量的时候,这个变量值就是undefined 1 var hi; ...

  5. 正则表达式从右往左进行匹配(Regex)

    #匹配最末两位为数字 $x=New-Object regex ('\d{2}','RightToLeft') #$x.RightToLeft $x.Match('abcd22') 结果:

  6. [ALGO-3] K好数

    算法训练 K好数   时间限制:1.0s   内存限制:256.0MB 问题描写叙述 假设一个自然数N的K进制表示中随意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数 ...

  7. 使用Filter防止浏览器缓存页面或请求结果

    仅仅须要两步: 1.定义一个Filter: /** * 防止浏览器缓存页面或请求结果 * @author XuJijun * */ public class NoCacheFilter impleme ...

  8. cdoj 1255 斓少摘苹果 贪心

    斓少摘苹果 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1255 Descr ...

  9. Masonry+Infinite-Scroll实现无刷新无分页完美瀑布流(转)

    一.Masonry 是基于Jquery插件,用于对CSS布局的可移动层进行重新布局.Masonry愿意石工,可以这样形象的理解,页面上很多大小不一的移动层可以想象成散乱的石头,经过Masonry这个石 ...

  10. grunt自动化工具

    Grunt和 Grunt 插件是通过 npm 安装并管理的,npm是 Node.js 的包管理器. 安装 CLI 首先,需要先将Grunt命令行(CLI)安装到全局环境中. npm install - ...