在处理一些集合、数组、泛型集合的时候都是遍历进行操作,现在想想真的觉得太垃圾了,有更简单的方法为什么不总结一下那?
微软的官方文档地址,可以好好研究一下
微软关于linq命名空间下的方法集合
关于Enumerable类
此类中的方法提供了标准查询运算符的实现,用于查询实现的数据源 IEnumerable 。 标准查询运算符是遵循模式的常规用途方法, LINQ 使您能够对任何中的数据进行遍历、筛选和查找操作。
此类中的大多数方法都定义为扩展方法 IEnumerable 。 这意味着,可以像调用实现的任何对象上的实例方法一样调用它们 IEnumerable
研究之前先看一下Func
Func这个方法实际上是一个委托
定义一个func的委托,需要注意func的参数比较特殊,最后一个参数是当作返回值类型的的,下图中已经用黄色框标出,是一个out类型的参数。
定义之后用invoke方法进行执行。
输出结果就是两个字符串参数的相加:“你的我的”
在声明func委托的时候,注意参数a,b一定属于string类型,这样的写法是Lambda表达式
有了这些基础开始往下看linq
Func<string, string, string> func = (a, b) => a + b;
string ss = func.Invoke("你的", "我的");
Aggregate()累加器
Aggregate()有三个参数的重载,每个方法的使用都不用。
public static TSource Aggregate<TSource> (IEnumerable<TSource> source, Func<TSource,TSource,TSource> func);
//下面是官方文档给出的例子
string sentence = "the quick brown fox jumps over the lazy dog";
//按照空格将string转换成数组
string[] words = sentence.Split(' ');
string reversed = words.Aggregate((workingSentence, next) => next + " " + workingSentence);
//reversed=dog lazy the over jumps fox brown quick the
Console.WriteLine(reversed);
迷惑的地方是就是words.Aggregate((workingSentence, next) => next + " " + workingSentence);
在调用这个方法的时候,这两个参数:“workingSentence”,“next”,从哪里来的,为啥没定义就能拿过来用了。其实这个就是Lambda表达式的一种写法,先说一下,workingSentence:其实就是数组words中的第一个参数,next就是下一个。说白了
words.Aggregate((workingSentence, next)这个玩意就是一个循环。看成for循环就好了。唯一不同的就是workingSentence永远开始是第一个值,但是内部执行的结果由workingSentence去接收。next就是从从第二个开始一直循环到最后一个。
我们可以打印一下,看一下值
string sentence = "the quick brown fox jumps over the lazy dog";
//生成一个string类型的数组
string[] words = sentence.Split(' ');
string result = words.Aggregate((a, b) =>
{
Console.WriteLine("a的值是:" + a);
Console.WriteLine("b的值是:" + b);
Console.WriteLine("**********");
return b + " " + a;
});
Console.WriteLine("现在的result的值是:" + result);
可以看出,第一次循环的时候,a的值就是 数组 words的第一个:“the”。参数b不断的循环,从第二个一直到最后一个。然后把参数b和a的值相加,赋值给a。参数a开始是代表了第一个参数,但是随着循环开始,不断的被赋值新的结果(b+a)
接下来看另外一个Aggregate()方法的使用:
public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func);
这个的重载比较特殊,需要给定一个初始值:如下代码:
string sentence = "the quick brown fox jumps over the lazy dog";
//生成一个string类型的数组
string[] words = sentence.Split(' ');
string res = words.Aggregate("66", (a, b) =>
{
Console.WriteLine("a的值是:" + a);
Console.WriteLine("b的值是:" + b);
return a;
});
Console.WriteLine(res);
Console.ReadKey();
给定的这个初始值 “66”,在函数执行的过程中,赋值给了参数a,在函数返回参数a的方法中,a一直是“66”
也就是说,只要给定一个具体值, **string res = words.Aggregate(“66”, (a, b)**给定的一个初始值66,将会赋值给参数a,当作a的第一个参数,此时参数a就不会是words[0]了,b是成了words[0],并且b不断循环。
//声明一个int类型的数组
int[] ints = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int result = ints.Aggregate(100, (a, b) =>
{
Console.WriteLine("a的值是:" + a);
Console.WriteLine("b的值是:" + b);
return a + b;
});
Console.WriteLine(result);
Console.ReadKey();
运行的结果是: