C# 中奇妙的函数 -- 1. ToLookup
2011-04-06 21:10
381 查看
这个系列,我和大家一起来学学C#中一些非常有用函数,对于有些人来说可能它们不起眼,因此常常忽略它们。它们不会嚷嚷到:“使用我吧!我会让你节省很多的时间,而且让你的代码变得更加的简洁!” -- 但是,这些话会从对它们熟悉的程序员的脑海中涌现出来。
好的!先来看看ToLookup:
下文参考翻译自:
然后我们加入一个函数得到一个产品的列表,当然你也可以从数据库中读取出来:
我们有一个任务就是按类别列出一个物品清单,这个非常的容易,用GroupBy 就可以实现了:
看起来一切都很好,没有什么问题.
当我们使用 GroupBy() 扩展方法时,使用了延迟执行。 这意味着,当你遍历集合的时候,下一个要出现的项目可能会或者可能不会被加载。 这是一个很大的性能改进,但它会引起有趣的副作用。
在用 GroupBy()时, 它实际上是在第一项被使用的时候创建分组,而不是在 GroupBy() 第一次被调用时。
考虑一下:如果你从数据库中加载数据,然后想组合到一起,并存储快速查找。 看下面的一段代码:
执行后发现,所有的Garden产品都已经消失了,但是 groups 是在执行删除命令前就已经赋值了。
基于这种情况,我们不得不使用ToDictionary() 将GroupBy 后的结果储存起来,这样一来工作量就增加了,而且维护也不太方便 -- 请大家试试。
该 ToLookup() 方法创建一个类似 字典(Dictionary ) 的列表List, 但是它是一个新的 .NET Collection 叫做 lookup。 Lookup,不像Dictionary, 是不可改变的。 这意味着一旦你创建一个lookup, 你不能添加或删除元素。
你还可以使用类似索引的功能得到某个项目,在本案例中是得到某个类别的所有产品:
好的!先来看看ToLookup:
下文参考翻译自:
C#/.NET Little Wonders: The ToLookup() LINQ Extension Method
故事的背景
让我们先来创建一个简单的类来表示产品,产品有ID,类别,和价格,这个类没有什么特别:public sealed class Product { public int Id { get; set; } public string Category { get; set; } public double Value { get; set; } public override string ToString() { return string.Format("[{0}: {1} - {2}]", Id, Category, Value); } }
然后我们加入一个函数得到一个产品的列表,当然你也可以从数据库中读取出来:
public static List<Product> GetList() { var products = new List<Product> { new Product {Id = 1, Category = "Electronics", Value = 15.0}, new Product {Id = 2, Category = "Groceries", Value = 40.0}, new Product {Id = 3, Category = "Garden", Value = 210.3}, new Product {Id = 4, Category = "Pets", Value = 2.1}, new Product {Id = 5, Category = "Electronics", Value = 19.95}, new Product {Id = 6, Category = "Pets", Value = 21.25}, new Product {Id = 7, Category = "Pets", Value = 5.50}, new Product {Id = 8, Category = "Garden", Value = 13.0}, new Product {Id = 9, Category = "Automotive", Value = 10.0}, new Product {Id = 10, Category = "Electronics", Value = 250.0}, }; return products; }
我们有一个任务就是按类别列出一个物品清单,这个非常的容易,用GroupBy 就可以实现了:
foreach (var group in products.GroupBy(p => p.Category)) { Console.WriteLine(group.Key); foreach (var item in group) { Console.WriteLine("\t" + item); } }
看起来一切都很好,没有什么问题.
当我们使用 GroupBy() 扩展方法时,使用了延迟执行。 这意味着,当你遍历集合的时候,下一个要出现的项目可能会或者可能不会被加载。 这是一个很大的性能改进,但它会引起有趣的副作用。
在用 GroupBy()时, 它实际上是在第一项被使用的时候创建分组,而不是在 GroupBy() 第一次被调用时。
考虑一下:如果你从数据库中加载数据,然后想组合到一起,并存储快速查找。 看下面的一段代码:
var groups = products.GroupBy(p => p.Category); //删除所有属于Garden的产品 products.RemoveAll(p => p.Category == "Garden"); foreach (var group in groups) { Console.WriteLine(group.Key); foreach (var item in group) { Console.WriteLine("\t" + item); } }
执行后发现,所有的Garden产品都已经消失了,但是 groups 是在执行删除命令前就已经赋值了。
基于这种情况,我们不得不使用ToDictionary() 将GroupBy 后的结果储存起来,这样一来工作量就增加了,而且维护也不太方便 -- 请大家试试。
ToLookup登场
现在我们有请ToLookup。该 ToLookup() 方法创建一个类似 字典(Dictionary ) 的列表List, 但是它是一个新的 .NET Collection 叫做 lookup。 Lookup,不像Dictionary, 是不可改变的。 这意味着一旦你创建一个lookup, 你不能添加或删除元素。
var productsByCategory = products.ToLookup(p => p.Category);
foreach (var group in productsByCategory) { // the key of the lookup is in key property Console.WriteLine(group.Key); // the list of values is the group itself. foreach (var item in group) { Console.WriteLine("\t" + item); } }
你还可以使用类似索引的功能得到某个项目,在本案例中是得到某个类别的所有产品:
private static void PrintCategory(ILookup<string, Product> productsByCategory,string categoryName) { foreach (var item in productsByCategory[categoryName]) { Console.WriteLine(item); } }
源代码下载
你从这里可以下载本案例的源码结论
ToLookup() 是一个奇妙的函数,用于对一个集合进行操作,创建一个1:n 的映射。 它可以方便的将数据分类成组,并生成一个字典供查询使用。相关文章推荐
- 鲜为人知的奇妙函数List的ToLookup(LINQ Extension Method)
- 挖一挖C#中那些我们不常用的东西之系列(1)——ToDictionary,ToLookup
- C#探秘系列(一)――ToDictionary,ToLookup
- C# ToLookup
- 挖一挖C#中那些我们不常用的东西之系列(1)——ToDictionary,ToLookup
- 挖一挖C#中那些我们不经常使用的东西之系列(1)——ToDictionary,ToLookup
- 挖一挖C#中那些我们不常用的东西之系列(1)——ToDictionary,ToLookup
- 一起谈.NET技术,C# 中奇妙的函数之ToLookup
- [C#.Net&Linq]LINQ to Object 学习笔记(资料群组GroupBy、ToLookup、ToDictionary)
- C#探秘系列(一)——ToDictionary,ToLookup
- C#“.NET技术” 中奇妙的函数--联接序列的五种简单方法
- <From C++ To C#>进军到函数
- C# 中奇妙的函数--联接序列的五种“.NET研究”简单方法
- 零碎的小知识点 ----------C# ToString()函数注意事项
- C# 中奇妙的函数 -- 1. ToLookup
- LINQ标准查询操作符(四)—AsEnumerable,Cast,OfType,ToArray,ToDictionary,ToList,ToLookup,First,Last,ElementAt
- How do I use a host name to look up an IP address?
- C# 中奇妙的函数–8. String Remove() 和 Replace()
- LINQ 标准的查询操作符 转换 ToList()、ToLookup()、ToEnumerable()、ToDictionary、ToType<T>
- 获取Android源码时如何解决【fatal: Unable to look up android.git.kernel.org (port 9418) (Name or service not kn