LINQ
LINQ指的是 Language Integrate Query
1. 初体验
分别使用静态方法,实例方法,查询语句进行LINQ查询
string[] strs = {
"times", "get", "gives" ,"month"};
//使用静态方法
IEnumerable<string> strEnum =
System.Linq.Enumerable.Where(strs, n => n.Length >= 4);
foreach (var item in strEnum)
{
Console.WriteLine(item);
}
Console.WriteLine("---------------");
//使用实例方法
IEnumerable<string> strE2 = strs.Where(n => n.Length > 4).Skip(1);
foreach (var item in strE2)
{
Console.WriteLine(item);
}
Console.WriteLine("---------------");
//使用查询语句
IEnumerable<string> worEnu = from n in strs where n.Contains('e') select n;
foreach (var item in worEnu)
{
Console.WriteLine(item);
}
//times
//gives
//month
//---------------
//gives
//month
//---------------
//times
//get
//gives
1.1 流式语句
流式语句,就是一连串的条件进行限定。流式方法和静态方法可以相互转换。
string[] strs = {
"time", "get", "gives" ,"month","Tom","Jerrys"};
//流式方法
IEnumerable<string> strEnu = strs.Where(n=>n.Length>3)
.Where(n=>n.Contains("e"))
.OrderBy(n => n.Length);
foreach (var item in strEnu)
{
Console.WriteLine(item);
}
Console.WriteLine("-------------");
//等价于以下的静态方法
IEnumerable<string> strWhereEnu = Enumerable.Where(strs, n => n.Length > 3);
IEnumerable<string> strWhereCon = Enumerable.Where(strWhereEnu, n => n.Contains('e'));
IOrderedEnumerable<string> strOrderEnu = Enumerable.OrderBy(strWhereCon, n => n.Length);
foreach (var item in strOrderEnu)
{
Console.WriteLine(item);
}
//time
//gives
//Jerrys
//-------------
//time
//gives
//Jerrys
1.2 序列相关部分运算符
Take 运算符:Take 是拿出序列的几个数
Skip 运算符:Skip 是跳过序列的前几个数
- Reverse 运算符:Reverse 是将序列反转
string[] strs = {
"time", "get", "gives" ,"month","Tom","Jerrys"};
foreach (var item in strs.Take(3))
{
Console.WriteLine(item);
}
Console.WriteLine("--------------");
foreach (var item in strs.Skip(3))
{
Console.WriteLine(item);
}
Console.WriteLine("--------------");
foreach (var item in strs.Reverse())
{
Console.WriteLine(item);
}
//time
//get
//gives
--------------
//month
//Tom
//Jerrys
--------------
//Jerrys
//Tom
//month
//gives
//get
//time
- Contcat 运算符:连接两个字符串,有重复元素也连接在一起
- Union 元算符:联合两个字符串,有重复元素就省略重复的元素
string[] strs = {
"time", "get" ,"Jim"};
string[] strtemp = {
"month", "Tom", "Jim" };
foreach (var item in strs.Concat(strtemp))
{
Console.WriteLine(item);
}
Console.WriteLine("------------------");
foreach (var item in strs.Union(strtemp))
{
Console.WriteLine(item);
}
//time
//get
//Jim
//month
//Tom
//Jim
//------------------
//time
//get
//Jim
//month
//Tom
1.3 查询相关部分运算符
- First,获取序列第一个元素
- Last,获取序列最后一个元素
- ElementAt,获取序列的某一个索引元素
- Min,获取序列最小值
- Count,获取序列元素的个数
- Any,是否有元素满足某个条件,如果有一个满足就返回true
- All,与Any相反,但是这个必须要有一个判断条件
string[] strs = {
"time", "get", "gives" ,"month","Tom","Jerrys"};
Console.WriteLine(strs.First());
Console.WriteLine(strs.Last());
Console.WriteLine(strs.ElementAt(2));
Console.WriteLine(strs.Min());
Console.WriteLine(strs.Count());
Console.WriteLine(strs.Any());
Console.WriteLine(strs.Any(n=>n.Length>5));
Console.WriteLine(strs.All(n=>n.Length>4));
//time
//Jerrys
//gives
//get
//6
//True
//True
//False
2.查询表达式
- 延迟执行特性:查询语句构造完成后, 并不会立即执行,而是等到foreach里面才执行,在这执行之前,如果新增了元素,那么元素在foreach里也或生效。
- 临时使用外部变量:当foreach前改变lambda表达式里面的外部变量值,那么构造的语句也会根据外部变量改变而改变
//延迟执行特性
List<int> list = new List<int> {
1 };
IEnumerable<int> intEnu = list.Select(n => n * 10);
list.Add(2);
foreach (var item in intEnu)
{
Console.WriteLine(item);
}
//10
//20
//临时修改外部变量
List<int> list = new List<int> {
1,2};
int mul = 10;
IEnumerable<int> intEnu = list.Select(n => n * mul);
foreach (var item in intEnu)
{
Console.WriteLine(item);
}
Console.WriteLine("-----------------");
//临时修改外部变量
mul = 100;
foreach (var item in intEnu)
{
Console.WriteLine(item);
}
//10
//20
//-----------------
//100
//200
3. 子查询
就是把一个LINQ作为另一个LINQ的输入
4. into 关键字
使用into关键字,将原始查询重命名,其他都是一样的,性能也不变。
另外,into关键字只能在Select和Group后面添加。
string[] names = {
"Tom", "Jerry", "kate", "Lucy", "Micky" };
IEnumerable<string> strName =
from n in names
where names.Length > 3
select n.Replace('y', 'Y')
into na
where na.Length > 3
select na;
foreach (var item in strName)
{
Console.WriteLine(item);
}
//JerrY
//kate
//LucY
//MickY
5. 使用LINQ进行对象初始化
5.1 对象类型
需要声明定义一个对象类,然后使用select 配合new关键字进行对象初始化。
string[] names = {
"Tom", "Jerry", "kate", "Lucy", "Micky","li" };
IEnumerable<Person> query =
from p in names
select new Person
{
name = p,
liName = p.ToLower()
};
foreach (var item in query)
{
Console.WriteLine(item.name+","+item.liName);
}
Console.WriteLine("---------------------");
//继续使用上面的查询作为输入
IEnumerable<string> strName =
from n in query
where n.name.Length > 2
orderby n.name.Length descending
select n.name + "," + n.liName;
foreach (var item in strName)
{
Console.WriteLine(item);
}
//输出
//Tom,tom
//Jerry,jerry
//kate,kate
//Lucy,lucy
//Micky,micky
//li,li
//---------------------
//Jerry,jerry
//Micky,micky
//kate,kate
//Lucy,lucy
//Tom,tom
5.2 匿名类型
可以不用声明定义一个对象,直接使用new,然后直接赋值即可
string[] names = {
"Tom", "Jerry", "kate", "Lucy", "Micky", "li" };
var query =
from n in names
select new
{
name = n,
liName = n.ToLower()
};
foreach (var item in query)
{
Console.WriteLine(item.liName+","+item.name);
}
Console.WriteLine("--------------");
IEnumerable<string> strName =
from n in query
where n.name.Length > 2
orderby n.name.Length descending
select n.name + "," + n.liName;
foreach (var item in strName)
{
Console.WriteLine(item);
}
//输出
tom,Tom
jerry,Jerry
kate,kate
lucy,Lucy
micky,Micky
li,li
--------------
Jerry,jerry
Micky,micky
kate,kate
Lucy,lucy
Tom,tom
使用两个数组,分别取出两个数组元素的索引,进行比较,然后拼接成一个匿名对象,进行输出。
string[] names = {
"Tom", "Jerry", "kate", "Lucy", "Micky", "li" ,"zh"};
int[] ages = {
10, 20, 50, 12, 45, 20 };
var indexedItems = names.Select((value, index) => new {
Index = index, Value = value });
var dicar =
from n in names.Select((value, index) => new {
Index = index, Value = value })
join a in ages.Select((value, index) => new {
Index = index, Value = value }) on n.Index equals a.Index
select new
{
name = n.Value,
age = a.Value
};
foreach (var item in dicar)
{
Console.WriteLine($"{item.name},{item.age}");
}
//输出
Tom,10
Jerry,20
kate,50
Lucy,12
Micky,45
li,20
6. let 关键字
let关键字作用是,能够在LINQ中使用一个临时变量来储存临时结果,然后对这个临时结果进行处理。
string[] names = {
"Tom", "Jerry", "kate", "Lucy", "Micky", "li", "zh" };
var query =
from n in names
let temp = n.Replace('y', 'Y')
where temp.Length > 2
orderby temp descending
select temp;
foreach (var item in query)
{
Console.WriteLine(item);
}
//输出
Tom
MickY
LucY
kate
JerrY