使用LINQ的几个小技巧
这里总结了这些技巧。介绍如何使用LINQ来:
- 初始化数组
- 在一个循环中遍历多个数组
- 生成随机序列
- 生成字符串
- 转换序列或集合
- 把值转换为长度为1的序列
- 遍历序列的所有子集
如果你在LINQ方面有心得也欢迎在评论中一起分享。
1. 初始化数组
通常,我们需要把数组的值初始化为相同的值或递增的序列值,或者可能是一个步进不为1的递增/递减序列。有了LINQ,我们可以在数组的初始化器中完成所有工作,不再需要循环!
在如下的示例代码中,第一行代码初始化了一个长度为10的数组,所有元素都是-1,第二行代码初始化b为0、1、2到9,第三行代码初始化c为100、110、120到190.
int[] a = Enumerable.Repeat(-1, 10).ToArray();
int[] b = Enumerable.Range(0, 10).ToArray();
int[] c = Enumerable.Range(0, 10).Select(i => 100 + 10 * i).ToArray();
要提醒一下:如果你初始化一个很大的数组,最好不考虑这种优雅的方式而是使用传统的方式来替代。LINQ的这种解决方案会动态产生数组,因此垃圾数组需要在运行时被回收。也就是说,我总是会在小数组或测试调试代码的情况下使用这种技巧。
2. 在一个循环中遍历多个数组
有个朋友问我一个C#的问题:有没有办法在一个循环中遍历多个集合?他的代码差不多是这样:
foreach (var x in array1) {
DoSomething(x);
}
foreach (var x in array2) {
DoSomething(x);
}
这样的话,循环主体会很大,而且他也不希望这样重复的代码。但是,他又不希望创建一个数组来保存array1和array2的所有元素。
LINQ提供了一种优雅的解决方案:Concat操作。我们可以使用单个循环来重写上面的代码,如下:
foreach (var x in array1.Concat(array2)) {
DoSomething(x);
}
注意,由于LINQ在枚举器级别进行操作,他不会产生新的数组来保存array1和array2的元素。因此,除了优雅之外,这个方案还很高效。
3. 生成随机序列
这是一个生成N长度随机序列的简单技巧:
Random rand = new Random();
var randomSeq = Enumerable.Repeat(0, N).Select(i => rand.Next());
有了LINQ的延迟特性,序列不会实现进行计算并保存到数组中,而是在迭代randomSeq的时候按需生成随机数。
4. 生成字符串
LINQ同样也是生成各种类型字符串的好工具。对于测试或调试,生成字符串时很有用的。假设我们需要生成一个N长度的字符串,按照“ABCABCABC”的方式。使用LINQ,解决方案非常优雅:
string str = new string(
Enumerable.Range(0, N)
.Select(i => (char)(‘A’ + i % 3))
.ToArray());
Petar Petrov给出了另外一种有趣的方式使用LINQ来生成字符串:
string values = string.Join(string.Empty, Enumerable.Repeat(pattern, N).ToArray());
5. 转换序列或集合
在C#或VB中我们不能实现把序列从T类型转换为U类型,即使T从U类继承。因此,即使把List<string>转换为List<object>也很难实现。(要解释为什么,请看Bick Byer的帖子)。但是如果要把IEnumerable<T>转换为IEnumerable<U>的话,LINQ有一个简单而有效的解决方案:
IEnumerable<string> strEnumerable = …;
IEnumerable<object> objEnumerable = strEnumerable.Cast<object>();
如果我们需要转换List<T>为List<U>,LINQ也提供了解决方案,但是它会进行列表的复制:
List<string> strList = …;
List<object> objList = new List<object>(strList.Cast<object>());
Chris Cavanagh建议另外一种解决方式:
var objList = strList.Cast<object>().ToList();
6. 把值转换为长度为1的序列
当我们需要把单个值转化为一个长度为1的序列时,会怎么做?我们可以创建一个长度为1的数组,但是我还是喜欢LINQ的Repeat操作:
IEnumerable<int> seq = Enumerable.Repeat(myValue, 1);
7. 遍历序列的所有子集
有的时候,遍历数组的所有子集很有用。子集和问题、布尔可满足性问题以及背包问题都可以通过遍历某个序列的所有子集来简单解决。
有了LINQ,我们可以如下声场所有arr数组的子集:
T[] arr = ...;
var subsets = from m in Enumerable.Range(0, 1 << arr.Length)
select
from i in Enumerable.Range(0, arr.Length)
where (m & (1 << i)) != 0
select arr[i];
注意,如果子集的个数超过了int,上面的代码就不能工作。因此,仅当你知道arr的长度不超过30的时候才去使用这个方式。如果arr长度超过30,你应该不会是想去遍历所有的子集,因为可能这会耗费几分钟或更长的时间。
评论和总结
希望这些技巧对你有用,这些示例代码都使用C#实现,但是你可以很容易得改变为其它.NET语言。然而,LINQ对于支持扩展方法、lambda表达式和类型推断的语言更方便,比如C#和VB。这里的每一段代码都可行,但是我不能保证什么,请在使用前仔细检查。
使用LINQ的几个小技巧的更多相关文章
- C#解决Linq OrderBy() 失效的小技巧
前言 前几天的一个数据列表中我用了Linq GroupBy 和OrderBy. 排序在本机正常使用,发到测试后排序死活不对,很是郁闷,总以为是程序问题.于是请教了另外一个同事.有了以下的答案. 问题原 ...
- IT咨询顾问:一次吐血的项目救火 java或判断优化小技巧 asp.net core Session的测试使用心得 【.NET架构】BIM软件架构02:Web管控平台后台架构 NetCore入门篇:(十一)NetCore项目读取配置文件appsettings.json 使用LINQ生成Where的SQL语句 js_jquery_创建cookie有效期问题_时区问题
IT咨询顾问:一次吐血的项目救火 年后的一个合作公司上线了一个子业务系统,对接公司内部的单点系统.我收到该公司的技术咨询:项目启动后没有规律的突然无法登录了,重新启动后,登录一断时间后又无法重新登 ...
- Win10 UWP开发中的重复性静态UI绘制小技巧 2
小技巧1 地址:http://www.cnblogs.com/ms-uap/p/4641419.html 介绍 我们在上一篇博文中展示了通过Shape.Stroke族属性实现静态重复性UI绘制,使得U ...
- C#中泛型方法与泛型接口 C#泛型接口 List<IAll> arssr = new List<IAll>(); interface IPerson<T> c# List<接口>小技巧 泛型接口协变逆变的几个问题
http://blog.csdn.net/aladdinty/article/details/3486532 using System; using System.Collections.Generi ...
- 前端网络、JavaScript优化以及开发小技巧
一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...
- Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具
前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率.至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好.我个人是比较 ...
- 分享两个BPM配置小技巧
1.小技巧 流程图修改后发布的话版本号会+1,修改次数多了之后可能会导致版本号很高,这个时候可以将流程导出,然后删除对应的流程包再导入,发布数据模型和流程图之后,版本清零 2.小技巧 有的同事入职后使 ...
- linux系统维护时的一些小技巧,包括系统挂载新磁盘的方法!可收藏!
这里发布一些平时所用到的小技巧,不多,不过会持续更新.... 1.需要将history创建硬链接ln 全盘需要备份硬链接 ln /etc/xxx /home/xxx 2.root用户不可以远程 /et ...
- JS处理事件小技巧
今天,就分享一下我自己总结的一些JS的小技巧: ①防止鼠标选中事件 <div class="mask" onselectstart="return false&qu ...
随机推荐
- android中ScrollView和GridView/ListView共存时,ScrollView不在顶部的解决方法
listView.setFocusable(false); gridView.setFocusable(false); 这个必须在代码中写,xml文件中设置不起作用 原文:http://stackov ...
- Apache配置支持include
Apache配置支持include 什么是SSI? SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思.从技术角度上说,SSI就是HTML文件中,可以通过注释 ...
- 工具类_java 数字转化为汉字大写
public class Num2Rmb { private String[] hanArr = { "零", "壹", "贰", &quo ...
- MyEclipse性能调优初体验
MyEclipse性能调优初体验 简介一下工作环境,MyEclipse2014,你懂的 项目中有一个基于web的工作流引擎,仅仅要执行起来就CPU差点儿耗尽(尽管看似27%,事实上已经把俺4核的CPU ...
- Windows Server 2012 R2 服务器管理器介绍和配置使用
1. 服务管理器是用于管理系统服务的管理工具.一般常用于windows系统,使用这个工具你可以启动.停止服务:设置服务是自动.手动启动或禁用:查看某个服务的相关信息:设置服务以什么用户启动等等(一般包 ...
- objective-C学习笔记(四)函数成员:方法(函数)
函数分为: 全局函数(C语言函数) 成员函数(OBJC方法):实例方法 “-” 和类方法“+”的区别 //这里要区别静态变量(类变量).全局函数.常量的区别 OBJC里面,所有方法默认为公有方法.没 ...
- ADO接口
转自百度文库 ADO中最重要的对象有三个:Connection.Recordset和Command,分别表示连接对象.记录集对象和命令对象. 三个对象对应的智能指针分别是:_ConnectionPtr ...
- BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币( dp )
背包dp.. -------------------------------------------------------------------------------- #include< ...
- OA项目总结
一.自定义拦截器: 继承AbstractInterceptor,覆写intercept方法,实现功能逻辑,最后在Struts.xml文件中配置了自定义拦截器,首先自定义拦截器栈, <!- ...
- Linux内核学习笔记-1.简介和入门
原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...