查询表达式

var lst = new List<int> {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};

var res = 
	from n in lst
	where n % 2 == 0 && n >= 4
	orderby n
	select n;

链式表达式

var lst = new List<int> {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};

var res = lst
	.Where(n => n >= 4 && n % 2 == 0)
	.OrderBy(n => n);

取两个数组的交集

var arr1 = new int[] {1, 2, 3, 4, 5, 6};
var arr2 = new int[] {4, 5, 6, 7, 8, 9};

var res = arr1.Intersect(arr2).Dump();

统计数字出现的频率

var rand = new Random(1334);
var arr = Enumerable.Range(0, 200).Select( _ => rand.Next(20));

var res = arr
	.GroupBy(x => x)
	.Select(g => new { g.Key, Count = g.Count()})
	.Dump();
var rand = new Random(1334);
var arr = Enumerable.Range(0, 200).Select( _ => rand.Next(20));

var res = arr
	.GroupBy(x => x)
	//.Select(g => new { g.Key, Count = g.Count()})
	.ToDictionary(g => g.Key, g => g.Count())
	.Dump();
var rand = new Random(1334);
var arr = Enumerable.Range(0, 200).Select( _ => rand.Next(20));

var res = 
	from x in arr
	group x by x into g
	select new { g.Key, Count = g.Count()};
	
res.Dump();

重要概念:延迟执行(defer)与消耗(exhaust)

延迟执行:在写query语句的时候,并没有执行,等到调用输出的时候,才执行了。
消耗:看结果的操作

并行消耗 ParallelQuery

实例

var urls = new string[] {
	"http://www.e.com/pic1.jpg",	
	"http://www.e.com/pic2.jpg",	
	"http://www.e.com/pic3.jpg",	
};

//var tasks = new List<Task>();
//foreach(var url in urls) 
//{
//	tasks.Add(DownloadAsync(url, url.Split('/').Last()));
//}

//链式表达式
var tasks = urls
	.Select(url => DownloadAsync(url, url.Split('/').Last()));

await Task.WhenAll(tasks);
"finish".Dump();

async Task DownloadAsync(string url, string fileName)
{
	await Task.Delay(1000);
	$"{fileName} downloaded.".Dump();
}

新手常犯的错误

  1. 常用的方法
  • Intersect() 求交集
  • First() Last() Average()
  • Count() First() Min() Sum() 可以传参
  • Max()和MaxBy()的区别
var arr = new List<int> {1, 2, 3, 4, 5, 6};
//找第一个元素或最后一个元素Last()
arr.Select(x => x).First();

//求平均数
//如果你有一个整数序列,调用Average()方法后将返回一个 double 类型的平均值。
//如果你有一个浮点数序列,调用Average()方法后将返回一个与输入序列相同的浮点数类型的平均值。
arr.Average();

//拿第一个偶数
arr.First(x => x % 2 == 0);

//获取所有偶数的数量
arr.Count(x => x % 2 == 0);

//按照某种规则排序然后获取
people.MaxBy(p => p.Age);

//default
people.FirstOrDefault(x => x.Age >= 22);
  1. 用着爽,但是丝毫不考虑开销
  • 滥用ToList(), arr.Where().OrderBy().ToList()[0]
  • 滥用Count(), Count() > 0
  • 滥用OrderBy(), 不用sort()
  • 不知道First()和Single()的区别
//这样的操作很费时间
bool res = arr.Where(x => x > 5000).Count() > 0;

//应该改成下面的操作,Any有短路机制,发现第一个就返回了
bool res = arr.Any(x => x > 5000);

//默认排序的话,直接用List的Sort()就行
//或者Array.Sort();,用于数组排序

//First()找到第一个就返回了,有短路机制
//Single()会保证是不是唯一的,他会遍历整个列表,有多个重复的元素的话会直接报错