C# Distinct方法的使用笔记
引自:http://blog.csdn.net/shaopengfei/article/details/36426763
从C# 3.0开始提供了Distinct方法,这对于集合的使用有了更为丰富的方法,经过在网上搜索相应的资源,发现有关这方面的写的好的文章还是不少的。而且为了扩展Linq的使用不方便的地方,有一些办法非常有效。由于本人工作中的需要,有一些功能暂时没有用到那么深入,现在只把最简单的一些功能分享出来,整理出来。
简单一维集合的使用:
- List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };
- List<string> names = new List<string> { "wang", "li", "zhang", "li", "wang", "chen", "he", "wang" };
- IEnumerable<int> distinctAges = ages.Distinct();
- Console.WriteLine("Distinct ages:");
- foreach (int age in distinctAges)
- {
- Console.WriteLine(age);
- }
- var distinctNames = names.Distinct();
- Console.WriteLine("\nDistinct names:");
- foreach (string name in distinctNames)
- {
- Console.WriteLine(name);
- }
- 在这段代码中,是最简单的Distinct()方法的使用。使用了集合接口IEnumerable,以及隐式类型var,至于这两种用法有什么区别,没有研究出来。
- 但是如果象下面这样的代码,是错误的!
- List<int> disAge = ages.Distinct();
- 正确的方法应该是:
- List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };
- List<int> disAge = ages.Distinct().ToList();
- foreach (int a in disAge)
- Console.WriteLine(a);
- 也就是说Distinct()方法的返回集合类型是一个接口,不是具体的集合,所以需要用一个ToList()。
自定义类的使用:
- 首先我们看MSDN上给出的例子,先定义一个产品类:
- public class Product : IEquatable<Product>
- {
- public string Name { get; set; }
- public int Code { get; set; }
- public bool Equals(Product other)
- {
- //Check whether the compared object is null.
- if (Object.ReferenceEquals(other, null)) return false;
- //Check whether the compared object references the same data.
- if (Object.ReferenceEquals(this, other)) return true;
- //Check whether the products' properties are equal.
- return Code.Equals(other.Code) && Name.Equals(other.Name);
- }
- // If Equals() returns true for a pair of objects
- // then GetHashCode() must return the same value for these objects.
- public override int GetHashCode()
- {
- //Get hash code for the Name field if it is not null.
- int hashProductName = Name == null ? 0 : Name.GetHashCode();
- //Get hash code for the Code field.
- int hashProductCode = Code.GetHashCode();
- //Calculate the hash code for the product.
- return hashProductName ^ hashProductCode;
- }
- }
- 在主函数里,是这样用的:
- static void Main(string[] args)
- {
- Product[] products =
- {
- new Product { Name = "apple", Code = 9 },
- new Product { Name = "orange", Code = 4 },
- new Product { Name = "apple", Code = 9 },
- new Product { Name = "lemon", Code = 12 }
- };
- //Exclude duplicates.
- IEnumerable<Product> noduplicates =
- products.Distinct();
- foreach (var product in noduplicates)
- Console.WriteLine(product.Name + " " + product.Code);
- }
- 这样的输出是:
- /*
- This code produces the following output:
- apple 9
- orange 4
- lemon 12
- */
- 但是现在的问题是,如果我们把主函数里改成这样:
- static void Main(string[] args)
- {
- Product[] products =
- {
- new Product { Name = "Smallapple", Code = 9 },
- new Product { Name = "orange", Code = 4 },
- new Product { Name = "Bigapple", Code = 9 },
- new Product { Name = "lemon", Code = 12 }
- };
- //Exclude duplicates.
- IEnumerable<Product> noduplicates =
- products.Distinct();
- foreach (var product in noduplicates)
- Console.WriteLine(product.Name + " " + product.Code);
- }
- 这样的输出是:
- /*
- This code produces the following output:
- Smallapple 9
- orange 4
- Bigapple 9
- lemon 12
- */
- 我们的问题是,如果想按Code来索引,想找出Code唯一的这些成员,那么这里就需要重新定义一个对Code比较的类,或者再扩展成泛型类,但是这样非常繁琐。
博客鹤冲天的改进办法(以下均转自这个博客)
- 首先,创建一个通用比较的类,实现IEqualityComparer<T>接口:
- public class CommonEqualityComparer<T, V> : IEqualityComparer<T>
- {
- private Func<T, V> keySelector;
- public CommonEqualityComparer(Func<T, V> keySelector)
- {
- this.keySelector = keySelector;
- }
- public bool Equals(T x, T y)
- {
- return EqualityComparer<V>.Default.Equals(keySelector(x), keySelector(y));
- }
- public int GetHashCode(T obj)
- {
- return EqualityComparer<V>.Default.GetHashCode(keySelector(obj));
- }
- }
- 借助上面这个类,Distinct扩展方法就可以这样写:
- public static class DistinctExtensions
- {
- public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector)
- {
- return source.Distinct(new CommonEqualityComparer<T, V>(keySelector));
- }
- }
- 下面的使用就很简单了:
- Product[] products =
- {
- new Product { Name = "Smallapple", Code = 9 },
- new Product { Name = "orange", Code = 4 },
- new Product { Name = "Bigapple", Code = 9 },
- new Product { Name = "lemon", Code = 12 }
- };
- var p1 = products.Distinct(p => p.Code);
- foreach (Product pro in p1)
- Console.WriteLine(pro.Name + "," + pro.Code);
- var p2 = products.Distinct(p => p.Name);
- foreach (Product pro in p2)
- Console.WriteLine(pro.Name + "," + pro.Code);
- 可以看到,加上Linq表达式,可以方便的对自定义类的任意字段进行Distinct的处理。
C# Distinct方法的使用笔记的更多相关文章
- 重写类的Equals以及重写Linq下的Distinct方法
当自定义一个类的时候,如果需要用到对比的功能,可以自己重写Equals方法,最整洁的方法是重写GetHashCode()方法. 但是,这个方法只适用于对象自身的对比(如if(a==b))以及字典下的C ...
- 如何很好的使用Linq的Distinct方法
Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1" Person3: Id=2, Name=&quo ...
- Linq的Distinct方法的扩展
原文地址:如何很好的使用Linq的Distinct方法 Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1&qu ...
- 【C#】详解使用Enumerable.Distinct方法去重
Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组.集合中的重复元素,还可以自定义去重的规则. 有两个重载方法 ...
- 如何使用Linq或EF来对数据去重——Distinct方法详解
刚开始接触LINQ时使用distinct去重时和大家一样遇到了一些麻烦,很感谢 http://www.cnblogs.com/A_ming/archive/2013/05/24/3097062.htm ...
- 扩展Linq的Distinct方法动态根据条件进行筛选
声明为了方便自己查看所以引用 原文地址:http://www.cnblogs.com/A_ming/archive/2013/05/24/3097062.html Person1: Id=1, Nam ...
- Linq Enumerable.Distinct方法去重
Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组.集合中的重复元素,还可以自定义去重的规则. 有两个重载方法 ...
- 【转载】C#中通过Distinct方法对List集合进行去重
在C#的List集合对象中,可以使用Distinct方法来对List集合元素进行去重,如果list集合内部元素为值类型,则Distinct方法根据值类型是否相等来判断去重,如果List集合内部元素为引 ...
- DISTINCT 方法用于返回唯一不同的值 。
DISTINCT 方法用于返回唯一不同的值 . 例如: $Model->distinct(true)->field('name')->select(); 生成的SQL语句是: SEL ...
随机推荐
- POJ 3922A Simple Stone Game
题目链接 A Sample Stone Game 题目大意:给定n,k,表示最初时有n个石头,两个人玩取石子游戏,第一个人第一次可以取1~n-1个石头,后面每个人最多可以拿走前面一个人拿走的个数的K倍 ...
- iptables实战系列:通过NAT转发实现私网对外发布信息
原文地址: http://os.51cto.com/art/201109/289486.htm [51CTO独家特稿]本文将介绍一个使用iptables实现NAT转发功能的案例. 本文假设读者已经对N ...
- 怎么SDCard上的获取相册照片
private String getRealPathFromURI(Uri contentUri) { Cursor cursor = null; String result = contentUri ...
- 破解中国电信华为无线猫路由(HG522-C)自己主动拨号+不限电脑数+iTV
中国电信总是把好好的一个路由猫阉割过后放在我的E家套餐里到处兜售(垄断市场也就罢了,还有非常多霸王条款,比方必须使用它们的手机,同一时候最多多少台电脑上网等等),曾经破解过另外一个中国电信的路由猫,非 ...
- URAL 1780 G - Gray Code 找规律
G - Gray CodeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view ...
- C#操作MySQL数据库-----HelloWorld
这里采用在visual studio 2010中通过MySql.Data.dll.MySql.Web.dll来连接mysql数据库, 之后便进行数据的插入和查询. Program.cs文件内容如下: ...
- Android Socket编程学习笔记
http://blog.csdn.net/eyu8874521/article/details/8847173 度娘给出的描述:通常也称作"套接字",用于描述IP地址和端口,是一个 ...
- Android开发之初识Camera图像采集
/* * Android开发之初识camera图像采集 * 北京Android俱乐部群:167839253 * Created on: 2011-8-24 * Author: blueeagle * ...
- web app页面要求
代码: <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum- ...
- 【每日一摩斯】-Index Skip Scan Feature (212391.1)
INDEX Skip Scan,也就是索引快速扫描,一般是指谓词中不带复合索引第一列,但扫描索引块要快于扫描表的数据块,此时CBO会选择INDEX SS的方式. 官方讲的,这个概念也好理解,如果将复合 ...