SQO

标准查询运算符SQO(Standard Query Operator),定义在System.Linq.Enumerable类中的50多个为IEnumerable<T>准备的扩展方法,这些方法用来对操作的集合进行查询筛选等操作。

编译器会转换LINQ查询,以调用方法而不是LINQ查询语句。

Where

  • 通过传入的lambda表达式筛选出集合中符合条件的所有元素并返回
  1. List<int> list = new List<int>() { 2, 20, 50, 18, 85, 56 };
  2. IEnumerable<int> res = list.Where(n => n > 40);

OfType<TResult>

  • 筛选出集合中数据类型为TResult的所有元素并返回
  1. var list = new ArrayList() { 20, "aaa", 40, "bbb", "ccc" };
  2. IEnumerable<string> res = list.OfType<string>();
  3. IEnumerable<int> res2 = list.OfType<int>();

Select

  • 投射操作符,用于将一个对象转换为另一个对象
  1. List<int> list = new List<int>() { 10, 20, 30, 40 };
  2. IEnumerable<Person> res = list.Select(n => new Person() { Age = n, Name = "" });

SelectMany

  • 将指定的函数的结果作为作为源数据投射到新的集合中
  1. List<Teacher> list = new List<Teacher>(){
  2. new Teacher(new List<Student>{
  3. new Student(){Name = "001",Score = 10},
  4. new Student(){Name = "002",Score = 20},
  5. new Student(){Name = "003",Score=30}}){Name = "ls1",Age=20},
  6. new Teacher(new List<Student>(){
  7. new Student(){Name = "004",Score=40},
  8. new Student(){Name = "005",Score=50}}){Name = "ls2",Age = 30},
  9. new Teacher(new List<Student>(){
  10. new Student(){Name= "006",Score=60},
  11. new Student(){Name = "007",Score=70}}){Name = "ls3",Age = 40}
  12. };
  13. var res = list.SelectMany(t => t.list, (t, s) => new { TName = t.Name, TAge = t.Age, SName = s.Name, SScore = s.Score });
  14. foreach (var item in res)
  15. {
  16. Console.WriteLine(item.TName + "--" + item.TAge + "--" + item.SName + "--" + item.SScore);
  17. }

OrderBy

  • 根据传入的lambda表达式对集合中的元素进行排序(升序)
  1. List<int> list = new List<int>() { 2, 20, 13, 30, 29, 50, 23 };
  2. List<Person> pList = new List<Person>() { new Person() { Name = "aa", Age = 20 }, new Person() { Name = "bb", Age = 13 } };
  3. IEnumerable<int> res = list.OrderBy(n => n);
  4. IEnumerable<Person> pRes = pList.OrderBy(p => p.Age);
  5. ThenBy 再次根据传入的lambda表达式对集合中的元素进行排序(升序)
  6. List<Person> list = new List<Person>() { new Person() { Name = "aa", Age = 20 }, new Person() { Name = "bb", Age = 13 } };
  7. IEnumerable<Person> res = list.OrderBy(p => p.Age).ThenBy(p => p.Name);
  8. OrderByDescending 根据传入的lambda表达式对集合中的元素进行排序(降序)
  9. List<Person> list = new List<Person>() { new Person() { Name = "aa", Age = 20 }, new Person() { Name = "bb", Age = 13 } };
  10. IEnumerable<Person> res = list.OrderByDescending(p => p.Age);
  11. ThenByDescending 再次根据传入的lambda表达式对集合中的元素进行排序(降序)
  12. List<Person> list = new List<Person>() { new Person() { Name = "aa", Age = 20 }, new Person() { Name = "bb", Age = 13 } };
  13. IEnumerable<Person> res = list.OrderByDescending(p => p.Age).ThenByDescending(p => p.Name);

Reverse

  • 翻转集合中元素的顺序(无返回值)
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. list.Reverse();//全部翻转
  3. list.Reverse(2, 3);//从索引为2的元素开始,翻转后边3个元素的顺序

Join

  • 连接操作符,通过指定的键合并不直接相关的集合
  1. List<Person> list = new List<Person>() { new Person() {ID=1, Name = "aa", Age = 20 }, new Person() {ID=2, Name = "bb", Age = 13 } };
  2. List<PersonInfo> pList = new List<PersonInfo>() { new PersonInfo() { ID = 1, Address = "......" }, new PersonInfo() { ID = 2, Address = "******" } };
  3. var res =list.Join(pList, p => p.ID, pi => pi.ID, (p, pi) => new { ID = p.ID, Name = p.Name, Age = p.Age, Address = pi.Address });

GroupBy

  • 根据传入的lambda表达式对集合中的元素进行分组
  1. List<Person> list = new List<Person>() { new Person() { ID = 1, Name = "aa", Age = 20 }, new Person() { ID = 2, Name = "bb", Age = 13 }, new Person() { ID = 3, Name = "cc", Age = 20 } };
  2. IEnumerable<IGrouping<int, Person>> res = list.GroupBy(p => p.Age);
  3. foreach (var item in res)
  4. {
  5. Console.WriteLine(item.Key);
  6. }

ToLookup

  • 通过创建一个一对多字典来组合元素
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50, 20, 40, 20, 40 };
  2. //IEnumerable<IGrouping<int, int>> res = list.GroupBy(a => a);//最终结果中不包含元素20
  3. ILookup<int, int> res = list.ToLookup(n => n);//最终结果包含元素20
  4. list.RemoveAll(n => n == 20);
  5. foreach (IGrouping<int, int> item in res)
  6. {
  7. Console.WriteLine("************" + item.Key + "*****************");
  8. foreach (int i in item)
  9. {
  10. Console.WriteLine(i);
  11. }
  12. }

Any

  • 返回集合中是否包含满足指定条件的元素
  1. List<Person> list = new List<Person>() { new Person() { ID = 1, Name = "aa", Age = 20 }, new Person() { ID = 2, Name = "bb", Age = 13 }, new Person() { ID = 3, Name = "cc", Age = 20 } };
  2. Console.WriteLine(list.Any());//集合中包含元素,返回True
  3. Console.WriteLine(list.Any(p => p.Age > 10));//集合中包含Age大于10的元素,返回True
  4. Console.WriteLine(list.Any(p => p.Age > 20));//集合中包含Age大于20的元素,返回False

All

  • 判断集合中所有元素是否满足指定条件
  1. List<Person> list = new List<Person>() { new Person() { ID = 1, Name = "aa", Age = 20 }, new Person() { ID = 2, Name = "bb", Age = 13 }, new Person() { ID = 3, Name = "cc", Age = 20 } };
  2. Console.WriteLine(list.All(p => p.Age > 10));//集合中所有元素的Age值都大于10,返回True
  3. Console.WriteLine(list.All(p => p.Age > 15));//集合中所有元素的Age值都大于15,返回False

Contains

  • 判断集合元素中是否包含指定的值
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Contains(30));//判断集合元素中是否包含30,返回True

Take

  • 从集合中获取指定个数的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. IEnumerable<int> res = list.Take(3);

Skip

  • 跳过指定个数的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. IEnumerable<int> res = list.Skip(2).Take(3);//跳过3个元素,获取后边的3个元素

TakeWhile

  • 依次获取集合中满足条件的元素,直到不满足条件时停止
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. IEnumerable<int> res = list.TakeWhile(n => n > 15);//结果res中没有元素,因为集合list中的第一个元素不满足条件,后边的元素就没有进行判断
  3. IEnumerable<int> res2 = list.TakeWhile(n => n < 30);//结果为10,20;当判断都集合中的第3个元素时,不满足条件,后边的元素就不进行判断
  4. IEnumerable<int> res3 = list.TakeWhile(n => n >= 10);//结果为10,20,30,10,50

SkipWhile

  • 依次跳过集合中满足条件的元素,直到不满足条件时停止
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. IEnumerable<int> res = list.SkipWhile(n => n < 30).Take(2);//结果为30,10

Distinct

  • 返回集合中非重复的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. IEnumerable<int> res = list.Distinct();//结果为10,20,30,50

Union

  • 返回两个集合的并集
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. List<int> list2 = new List<int>() { 20, 15, 40, 60 };
  3. IEnumerable<int> res = list.Union(list2);//结果为10,20,30,50,15,40,60

Intersect

  • 返回两个集合同时包含的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. List<int> list2 = new List<int>() { 20, 15, 40, 60 };
  3. IEnumerable<int> res = list.Intersect(list2);//结果为20

Except

  • 返回集合中存在,并且传入集合中不存在的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. List<int> list2 = new List<int>() { 20, 15, 40, 60 };
  3. IEnumerable<int> res = list.Except(list2);//结果为10,30,50

Zip

  • 将两个结合合并为一个
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. List<int> list2 = new List<int>() { 20, 15, 40, 60, 30 };
  3. IEnumerable<int> res = list.Zip(list2, (n, p) => n + p);//结果为30,35,70,70,80

First

  • 返回集合中第一个满足指定条件的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  2. Console.WriteLine(list.First());//10
  3. Console.WriteLine(list.First(n => n > 20));//30

FirstOrDefault

  • 返回集合中满足条件的第一个元素,如果所有元素都不满足条件求返回默认值
  1. List<Person> pList = new List<Person>() { new Person() { ID = 1, Name = "aa", Age = 20 }, new Person() { ID = 2, Name = "bb", Age = 13 }, new Person() { ID = 3, Name = "cc", Age = 20 } };
  2. List<int> list = new List<int>() { 10, 20, 30, 10, 50 };
  3. Console.WriteLine(list.First());//10
  4. Console.WriteLine(list.FirstOrDefault());//10
  5. Console.WriteLine(list.FirstOrDefault(n => n > 20));//30
  6. Console.WriteLine(list.FirstOrDefault(n => n > 100));//0
  7. Console.WriteLine(pList.FirstOrDefault(p => p.Age > 30));//Null

Last

  • 返回集合中最后一个满足指定条件的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Last());//50
  3. Console.WriteLine(list.Last(n => n < 40));//30

LastOrDefault

  • 返回集合中满足条件的最后一个元素,如果所有元素都不满足条件求返回默认值
  1. List<Person> pList = new List<Person>() { new Person() { ID = 1, Name = "aa", Age = 20 }, new Person() { ID = 2, Name = "bb", Age = 13 }, new Person() { ID = 3, Name = "cc", Age = 20 } };
  2. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  3. Console.WriteLine(list.Last());//50
  4. Console.WriteLine(list.LastOrDefault());//50
  5. Console.WriteLine(list.LastOrDefault(n => n < 40));//30
  6. Console.WriteLine(list.LastOrDefault(n => n > 100));//0
  7. Console.WriteLine(pList.LastOrDefault(p => p.Age > 30));//Null

ElementAt

  • 返回指定索引处的元素
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.ElementAt(2));//30

ElementAtOrDefault

  • 返回指定索引处的元素,如果索引超出范围,则返回默认值
  1. List<Person> pList = new List<Person>() { new Person() { ID = 1, Name = "aa", Age = 20 }, new Person() { ID = 2, Name = "bb", Age = 13 }, new Person() { ID = 3, Name = "cc", Age = 20 } };
  2. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  3. Console.WriteLine(list.ElementAtOrDefault(2));//30
  4. Console.WriteLine(list.ElementAtOrDefault(10));//0
  5. Console.WriteLine(pList.ElementAtOrDefault(10));//Null

Single

  • 返回集合中满足指定条件的唯一一个元素,如果有多个元素满足条件,则会引发异常
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Single(n => n > 40));//50
  3. Console.WriteLine(list.Single(n => n > 30));//异常:序列包含一个以上的匹配元素
  4. SingleOrDefault 返回集合中满足指定条件的唯一一个元素,如果集合为空或者集合中没有满足条件的元素,则返回默认值
  5. List<int> list = new List<int>();
  6. List<int> list2 = new List<int>() { 10, 20, 30, 40, 50 };
  7. Console.WriteLine(list.SingleOrDefault(n => n > 50));//0
  8. Console.WriteLine(list2.SingleOrDefault(n => n > 50));//0
  9. Console.WriteLine(list2.SingleOrDefault(n => n > 30));//异常:序列包含一个以上的匹配元素

Count

  • 返回集合中满足指定条件的元素个数
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Count(n => n > 50));//0
  3. Console.WriteLine(list.Count(n => n >= 10));//5

Sum

  • 返回集合中所有元素的和
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Sum());//150
  3. Console.WriteLine(list.Sum(n => n * 10 + 1));//1505

Min

  • 返回集合中所有元素的最小值
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Min());//10
  3. Console.WriteLine(list.Min(n => n % 3));//0

Max

  • 返回集合中所有元素的最大值
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Max());//50
  3. Console.WriteLine(list.Max(n => n % 3));//2

Average

  • 返回集合中元素的平均值
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Console.WriteLine(list.Average());//30
  3. Console.WriteLine(list.Average(n => n * 10+1));//301

Aggregate

  • 通过指定的函数对结合中的元素进行累加操作
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. List<string> list2 = new List<string>() { "I", "am", "ZhangSan", "!" };
  3. int sum = list.Aggregate((a, b) => a + b);
  4. string res = list2.Aggregate((s1, s2) => s1 + " " + s2);
  5. Console.WriteLine(sum);//150
  6. Console.WriteLine(res);//I am ZhangSan !

ToArray

  • 将集合中的元素复制到一个数组中,并返回该数组
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. int[] arr = list.ToArray();

AsEnumerable

  • 将集合转换为一个IEnumerable对象
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. IEnumerable<int> res = list.AsEnumerable();
  3. foreach (int i in res)
  4. {
  5. Console.WriteLine(i);
  6. }

ToList

  • 将操作对象转换为集合
  1. int[] arr = new int[] { 10, 20, 30, 40, 50 };
  2. arr.ToList();

ToDictionary

  • 将集合转换成字典对象
  1. List<int> list = new List<int>() { 10, 20, 30, 40, 50 };
  2. Dictionary<int, int> res = list.ToDictionary(n => n / 10);
  3. foreach (int item in res.Keys)
  4. {
  5. Console.WriteLine(item + "---" + res[item]);
  6. }

Cast<TResult>

  • 该方法通过提供必要的类型信息,是非泛型集合可以调用标准查询操作符
  1. ArrayList arr = new ArrayList() { "ff", "as" };//ArrayList类没有实现泛型接口IEnumerable<T>(实现了IEnumerable接口),所以无法使用Where()、Select()等标准查询操作符
  2. Enumerable<string> res = arr.Cast<string>().Select(a => a += "*");//通过Cast<T>转化之后就可以使用标准查询操作符

DefaultIfEmpty

  • 返回集合中的元素,如果集合为空,则返回指定的默认值
  1. List<int> list = new List<int>();
  2. List<int> list2 = new List<int>() { 10, 20, 30, 40, 50 };
  3. IEnumerable<int> res = list.DefaultIfEmpty(2);
  4. IEnumerable<int> res2 = list.DefaultIfEmpty(2);

Empty

  • 返回一个元素类型为指定类型的空集合
  1. IEnumerable<int> res = Enumerable.Empty<int>();
  2. Console.WriteLine(res.Count());

Range

  • 返回一个指定范围内的整数的序列
  1. IEnumerable<int> res = Enumerable.Range(10, 10);
  2. foreach (int item in res)
  3. {
  4. Console.WriteLine(item);
  5. }

Repeat

  • 生成一个包含重复值的序列
  1. IEnumerable<string> res = Enumerable.Repeat("abc", 10);
  2. foreach (string item in res)
  3. {
  4. Console.WriteLine(item);
  5. }