C# 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);
}
}
C# ToLookup的更多相关文章
- 挖一挖C#中那些我们不常用的东西之系列(1)——ToDictionary,ToLookup
这个系列我们看看C#中有哪些我们知道,但是又不知道怎么用,又或者懒得去了解的东西,比如这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,其中ToAr ...
- ToDictionary,ToLookup
这个系列我们看看C#中有哪些我们知道,但是又不知道怎么用,又或者懒得去了解的东西,比如这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,其中ToAr ...
- LINQ标准查询操作符(四) —AsEnumerable,Cast,OfType,ToArray,ToDictionary,ToList,ToLookup,First,Last,ElementAt
十.转换操作符 转换操作符是用来实现将输入对象的类型转变为序列的功能.名称以“As”开头的转换方法可更改源集合的静态类型但不枚举(延迟加载)此源集合.名称以“To”开头的方法可枚举(即时加载)源集合并 ...
- c# 敏捷2 ForEach ToDictionary ToLookup Except比较
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; ...
- 读书笔记 C# Lookup<TKey,TElement>和ToLookup方法的浅析
Lookup<TKey,TElement>类型对象和分组是一样的,就好比使用Linq的group关键字后所查询出来的结果,使用foreach的时候,都可以用IGrouping<TKe ...
- LINQ 学习路程 -- 查询操作 GroupBy ToLookUp
Grouping Operators Description GroupBy GroupBy操作返回根据一些键值进行分组,每组代表IGrouping<TKey,TElement>对象 To ...
- Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析
Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析 一:Tolookup 1. 从方法的注解上可以看到,ToLookup也是一个k,v的形式,那么问题来了,它 ...
- 挖一挖C#中那些我们不经常使用的东西之系列(1)——ToDictionary,ToLookup
这个系列我们看看C#中有哪些我们知道.可是又不知道怎么用.又或者懒得去了解的东西,比方这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,当中ToAr ...
- c# 中Linq Lambda 的ToLookup方法的使用
同样直接上代码: List<Student> ss = new List<Student>(); Student ss1 = , Age = , Name = " } ...
随机推荐
- vector排序
// VectorSort.cpp : Defines the entry point for the console application. // #include "stdafx.h& ...
- [ERROR] Terminal initialization failed; falling back to unsupported
Logging initialized using configuration in jar:file:/usr/local/hive/lib/hive-common-1.2.2.jar!/hive- ...
- 山东13年省赛 Aliceand Bob
Problem F: Alice and Bob Description Alice and Bob like playing games very much.Today, they introduc ...
- iTextSharpH
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- mybatis cloud not autowired
mybatis代码生成器生成的mapper在service引用的时候报cloud not autowired.... 即是在pom.xml中配置了不过滤mapper文件,报错还在 其实这不影响使用,但 ...
- vim快捷键与vi
vim与程序员 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主动的以字体 ...
- Vijos 1360 - 八数码问题 - [A*]
题目链接:https://vijos.org/p/1360 优先队列BFS: 这个八数码问题本身其实是之前人工智能实验课的作业…… 首先,如果不带估价函数,直接用优先队列BFS,肯定也是能得到正确结果 ...
- SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑 关键词:CDC 原文:http://www.cnblogs.com/chenxizhang/arc ...
- 使用JavaScript实现在页面上所有内容加载完之前一直显示loading...页面
Html <body class="is-loading"> <div class="curtain"> <div class=& ...
- ORA-00444: background process DBRM failed while starting
SQL> startup 报错:ORA-00444: background process DBRM failed while startingORA-00020:maximum number ...