助力查询学习 LinQ 查询语句的具体用法、可用于备忘 为初学者节省宝贵的时间,避免采坑! |
我们的初衷是将一种简单的生活方式带给世人 使有限时间 具备无限可能 |
Chinar 教程效果:
一
1. Where —— 筛选/过滤
Where —— 筛选满足条件的数据
找 重量大于 30的狗
List<Dog> dogs = new List<Dog>()
{
new Dog("金毛", 2000, 62),
new Dog("二哈", 1500, 45),
new Dog("泰迪", 1000, 15),
new Dog("吉娃娃", 500, 10)
};
//1-查询 狗狗中 重量大于30
dogs.Where(dog => dog.Weight > 30).ToList().ForEach(dog => print(dog.ToString()));
打印输出:
Name: 金毛, Price: 2000, Weight: 62
Name: 二哈, Price: 1500, Weight: 45
Name: 金毛, Price: 2000, Weight: 62
Name: 二哈, Price: 1500, Weight: 45
数据类 —— 为了简化代码,将该类放于
ChinarDemo.LinQ
命名空间中。便于以下例子使用此数据!
namespace ChinarDemo.LinQ
{
/// <summary>
/// 狗狗数据类
/// </summary>
public class Dog
{
public string Name; //名称
public int Price; //价格
public float Weight; //重量
/// <summary>
/// 构造 —— 简化代码
/// </summary>
public Dog(string name, int price, float weight)
{
Name = name;
Price = price;
Weight = weight;
}
/// <summary>
/// 便于打印输出看效果 —— 简化代码
/// </summary>
public override string ToString()
{
return $"{nameof(Name)}: {Name}, {nameof(Price)}: {Price}, {nameof(Weight)}: {Weight}";
}
}
}
2. Select —— 返回选定类型
Select —— 从数据中返回指定的数据类型
1:
从dogs序列中,返回狗的
名字新序列
2:从dogs序列中,返回狗的
价格新序列
3:从dogs序列中,返回狗的
重量新序列
List<Dog> dogs = new List<Dog>()
{
new Dog("金毛", 2000, 62),
new Dog("二哈", 1500, 45),
new Dog("泰迪", 1000, 15),
new Dog("吉娃娃", 500, 10)
};
dogs.Select(_=>_.Name).ToList().ForEach(_=>Console.WriteLine(_));//( 狗的名字 )返回新的序列
dogs.Select(_=>_.Price).ToList().ForEach(_=>Console.WriteLine(_));//( 狗的价格 )返回新的序列
dogs.Select(_ => _.Weight).ToList().ForEach(_ => Console.WriteLine(_));//( 狗的重量 )返回新的序列
打印输出:
金毛
二哈
泰迪
吉娃娃
2000
1500
1000
500
62
45
15
10
2.1 SelectMany —— 返回多个选定类型/协程排序
SelectMany —— 一个序列中每个元素的投影,合并为一个序列,并返回。
在 UniRx 中多用于对协程执行顺序进行管理
将狗狗的名字拆分为字符类型,并返回
对3个协程依照需求顺序执行
/// <summary>
/// 第一层
/// </summary>
public class One
{
public string Name; //名字
public int Age; //年龄
public List<Two> TwoList; //儿子
public One(string name, int age, List<Two> twoList)
{
Name = name;
Age = age;
TwoList = twoList;
}
}
/// <summary>
/// 第二层
/// </summary>
public class Two
{
public string Name; //名字
public int Age; //年龄
public List<Three> ThreeList; //儿子
public Two(string name, int age, List<Three> threeList)
{
Name = name;
Age = age;
ThreeList = threeList;
}
public override string ToString()
{
return $"{nameof(Name)}: {Name}, {nameof(Age)}: {Age}, {nameof(ThreeList)}: {ThreeList}";
}
}
/// <summary>
/// 第三层
/// </summary>
public class Three
{
public int Age; //年龄
public int Score; //分数
public Three(int age, int score)
{
Age = age;
Score = score;
}
public override string ToString()
{
return $"{nameof(Age)}: {Age}, {nameof(Score)}: {Score}";
}
}
class Program
{
static void Main(string[] args)
{
List<One> ones = new List<One> //第一层列表
{
new One("A1", 40, new List<Two> //第二层
{
new Two("A2_0", 20, new List<Three> {new Three(10, 100)}), //第三层
new Two("A2_1", 20, new List<Three> {new Three(10, 100)}), //第三层
new Two("A2_2", 20, new List<Three> {new Three(10, 100)}) //第三层
}),
new One("B1", 50, new List<Two>
{
new Two("B2", 30, new List<Three> {new Three(14, 70)})
}),
new One("C1", 70, new List<Two>
{
new Two("C2_0", 50, new List<Three> {new Three(25, 80)}),
new Two("C2_1", 50, new List<Three> {new Three(25, 80)})
}),
new One("D1", 80, new List<Two>
{
new Two("D2", 60, new List<Three> {new Three(40, 50)})
}),
};
#region 重载1
IEnumerable<List<Two>> onesSelect = ones.Select(_ => _.TwoList); //Select 返回 List<Two>
IEnumerable<Two> onesSelectMany = ones.SelectMany(_ => _.TwoList); //第一个重载:返回 Two
foreach (var v in onesSelect)
{
Console.WriteLine(v); //v=List<Two>
}
Console.WriteLine("----------------------------");
foreach (var v in onesSelectMany)
{
Console.WriteLine(v); //v=Two
}
#endregion
#region 重载 二
Console.WriteLine("----------重载 二 ------------");
//var onesSelectMany2 = ones.SelectMany((a, b) =>
// a.TwoList.Select(_ =>
// {
// _.Name = b + "---" + _.Name;
// return _;
// }));
//这里的 index 指的是 List<One> ones 中对象的索引
IEnumerable<string> onesSelectMany2 = ones.SelectMany((one, index) => one.TwoList.Select(_ => "索引:" + index + "--名字:" + _.Name));
foreach (var v in onesSelectMany2)
{
Console.WriteLine(v); //v=String
}
#endregion
Console.ReadLine();
}
打印输出:
3. First —— 首次/第一个数据
First —— 返回数据中的第一项数据
取数组中满足条件的 第一项 元素
int[] numbers = {1, 2, 3, 4, 5, 6}; //数组
var numFirst = numbers.First(i => i > 3); //返回满足条件的第一个数据元素
print(numFirst); //输出 4
打印输出:
4
4. Distinct —— 找不同
Distinct —— 不同的元素通过,相同元素被剔除
//一个数据列表,并添加数据
List<int> ints = new List<int>()
{
1, 2, 2, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
ints.Distinct().ToList().ForEach(_ => print(_)); //遍历输出,剔除后的列表
打印输出:
相同元素被剔除,返回不同的
12345678910
5. Last —— 找不同
Last —— 最后一个元素
找到狗狗中的最后一个/满足条件的最后一个
List<Dog> dogs = new List<Dog>()
{
new Dog("金毛", 2000, 62),
new Dog("二哈", 1500, 45),
new Dog("泰迪", 1000, 15),
new Dog("吉娃娃", 500, 10)
};
Dog dog = dogs.Last(); //最后一个
print(dog.ToString()); //:吉娃娃
Dog dog1 = dogs.Last(_ => _.Price > 1000); //传入条件:价格在 1000以上 的狗中的最后一个。这里由于数组是2000先加入,1500后加入。所以1500在后,返回的是1500。而并非2000
print(dog1.ToString()); //:二哈
打印输出:
Name: 吉娃娃, Price: 500, Weight: 10
Name: 二哈, Price: 1500, Weight: 45
6. Union —— 并集
Union —— 取2个集合的并集
其实就是 2个序列中,剔除所有重复元素,取唯一值合并为一个序列
剔除所有重复元素,取唯一,合并序列
int[] chinarArray1 = new int[] {1, 2, 3, 4, 5};
int[] chinarArray2 = new int[] {1, 4, 8, 6, 3, 2};
var unionList = chinarArray1.Union(chinarArray2).ToList();
string resultStr = "";
unionList.ForEach(_ => resultStr = resultStr + _.ToString());
print(resultStr);
打印输出:
1234586
7. (Min/Max/Count/Sum) —— 最小/最大/数量/求和
Min ——
序列中最小值
Max ——
序列中最大值
Count ——
序列元素的数量
Sum ——
序列中元素求和
数组中元素求和,取最大/最小值/元素数量
int[] ints = new[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
var min = ints.Min();
var max = ints.Max();
var count = ints.Count();
var sum = ints.Sum();
Console.WriteLine(min); //0
Console.WriteLine(max); //9
Console.WriteLine(count); //10
Console.WriteLine(sum); //45
打印输出:
0
9
10
45
8. OrderBy/Descending —— 升序/降序
OrderBy
—— 按照给定条件
对序列元素升序排序
OrderByDescending
—— 按照给定条件
对序列元素降序排序
将一个散乱的数组,升序,降序 排列
int[] ints = {5, 2, 8, 6, 4, 0, 3, 7, 9, 1}; //数字排序很乱的数组
var ascending = ints.OrderBy(_ => _).ToList(); //升序
var descending = ints.OrderByDescending(_ => _).ToList(); //降序
ascending.ForEach(Console.Write); //0123456789
Console.WriteLine(); //换行
descending.ForEach(Console.Write); //9876543210
Console.ReadKey();
打印输出:
0123456789
9876543210
9. Skip/Take —— 跳过、取定范围
基础都是依照 序列顺序 依次执行
Skip
——跳过指定数量元素,取剩余元素
SkipWhile
——根据(条件)
跳过指定数量元素,取剩余元素
Take
——只取指定数量元素,跳过剩余元素
TakeWhile
——根据(条件)
只取指定数量元素,跳过剩余元素
takeWhile0 坑点:
- 这里第一项就小于5,条件不满足返回 false
- 后边的元素就不再进行比较了,比较结束
- 所以没有取到任何元素,跳过了剩余所有元素。
- Count 为 0
![](https://i-blog.csdnimg.cn/blog_migrate/faa813cd7046bc66c2604b9b6ef29d2d.png)
SkipWhile
与TakeWhile
二者都是在条件为 false 时,结束比较
skip
跳过前10项,取剩余元素
skipWhile跳过小于 5 元素,取剩余元素
take只取前10项,跳过剩余元素
takeWhile只取小于 5 元素,跳过剩余元素
int[] ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
var skip = ints.Skip(10).ToList(); //跳过前 10 项元素,取剩余元素
var skipWhile = ints.SkipWhile(_ => _ < 5).ToList(); //跳过小于 5 元素,取剩余元素
var take = ints.Take(10).ToList(); //只取前 10 项元素,跳过剩余元素
var takeWhile = ints.TakeWhile(_ => _ < 5).ToList(); //只取小于 5 元素,跳过剩余元素
skip.ForEach(_ => Console.Write(_ + "-")); //10-11-12-13-14-15-16-17-18-19-
Console.WriteLine(); //
skipWhile.ForEach(_ => Console.Write(_ + "-")); //5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-
Console.WriteLine(); //
take.ForEach(_ => Console.Write(_ + "-")); //0-1-2-3-4-5-6-7-8-9-
Console.WriteLine(); //
takeWhile.ForEach(_ => Console.Write(_ + "-")); //0-1-2-3-4-
Console.WriteLine(); //
var takeWhile0 = ints.TakeWhile(_ => _ > 5).ToList();//跳过了所有元素,取不到任何元素
Console.WriteLine("takeWhile0 数量为:" + takeWhile0.Count);// 0
Console.ReadKey();
打印输出:
10-11-12-13-14-15-16-17-18-19-
5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-
0-1-2-3-4-5-6-7-8-9-
0-1-2-3-4-
takeWhile0 数量为:0
10. OfType —— 类型筛选
OfType
——根据指定类型,筛选对象
从一个 Object[]数组中,找出指定类型元素
找出类型为 Int 的元素
找出类型为 String 的元素
object[] objects = {1, 2, 3, 4, 5, "字符1", "字符2", "字符3"};
var intList = objects.OfType<int>().ToList(); //找出类型为 Int 的元素
var stringList = objects.OfType<string>().ToList(); //找出 String 元素
intList.ForEach(_ => Console.Write(_ + "-")); //1-2-3-4-5-
Console.WriteLine();
stringList.ForEach(_ => Console.Write(_ + "-")); //字符1-字符2-字符3-
Console.ReadKey();
打印输出:
1-2-3-4-5-
字符1-字符2-字符3-
11. Intersect —— 交集
Intersect
——取两个序列的交集,也就是两个序列的相同元素
两个数组序列中,找出相同元素,生成两个序列的交集
135
张三、李四
int[] ints1 = {1, 2, 3, 4, 5};
int[] ints2 = {1, 3, 5, 7, 9};
IEnumerable<int> intersectInts = ints1.Intersect(ints2);
//135 为两个数组相同元素,被返回
intersectInts.ToList().ForEach(Console.Write);
Console.WriteLine();
string[] strs1 = {"张三", "李四"};
string[] strs2 = {"张三", "李四", "王五", "干啥呢?"};
IEnumerable<string> intersectIntStrs = strs1.Intersect(strs2);
//张三、李四
intersectIntStrs.ToList().ForEach(Console.Write);
Console.ReadKey();
打印输出:
135
张三李四
12. Except —— 差集
Except
——取两个序列的差集,求出A、B中彼此没有的元素
Except 坑点:
- 序列A/B取差集,顺序不同,返回结果不同
- 也就是
A except B,与B except A
是不同d
![](https://i-blog.csdnimg.cn/blog_migrate/faa813cd7046bc66c2604b9b6ef29d2d.png)
要点就是:
A序列取B序列 —— 返回A有,B没有的值
B序列取A序列 —— 返回B有,A没有的值如此简单
将2个整数序列,1和2数组分别求差集
相互调换位置,看结果
int[] ints1 = {1, 2, 3, 4, 5}; //独有的为:2、4
int[] ints2 = {1, 3, 5, 7, 9}; //独有的为:7、9
var except12 = ints1.Except(ints2);
except12.ToList().ForEach(Console.Write); //24
Console.WriteLine();
Console.WriteLine("以下为 2 取 1");
var except21 = ints2.Except(ints1);
except21.ToList().ForEach(Console.Write); //79
Console.ReadKey();
打印输出:
24
以下为 2 取 1
79
支持
May Be —— 开发者,总有一天要做的事!
Chinar 提供一站式《零》基础教程 使有限时间 具备无限可能! |
Chinar 知你所想,予你所求!( Chinar Blog )
![](https://i-blog.csdnimg.cn/blog_migrate/791fc48379e30788cb90545b16e31c90.png)
![Chinar交流群 Chinar](http://pub.idqqimg.com/wpa/images/group.png)
本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究
对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址