LINQ笔记&实例

huuhghhgyg avatar
  • huuhghhgyg
  • 6 min read

LINQ:语言继承查询

限制运算符 Where

where语句的基本示例

1int[] numbers = {5,4,1,3,9,8,6,7,2,0};
2var lowNums = from num in numbers
3              where num < 5
4              select num; // 只选择小于5的数字

筛选符合属性条件的元素

1var soldOutProducts = from prod in products
2                      where prod.UnitsInStock == 0
3                      select prod; // 从集合中选出符合属性的元素

用多个条件筛选元素

1var expensiveInStockProducts = from prod in products
2                               where prod.UnitsInStock > 0 && prod.UnitPrice > 3.00M
3                               select prod; // 从集合中选出符合上述两个条件的元素

基于元素在列表中位置的筛选

1string[] digits = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
2var shortDigits = digits.Where((digit,index) => digit.Length < index);
3                  // 其中,index为元素的位置下标(从0开始),digit为digits的子元素。

以…开始 使用AutoSuggestBox控件 Xaml:

1<AutoSuggestBox Name="MyAutoSuggestBox" 
2                QueryIcon="Find" 
3                PlaceholderText="Search" 
4                TextChanged="MyAutoSuggestBox_TextChanged"/>

C#

1private string[] selectionItems = new string[] {"Ferdinand", "Nigel", "Tag",...};
2
3private void MyAutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs e)
4{
5    var autoSuggestBox = (AutoSuggestBox)sender;
6    var fileterd = selectionItems.Where(p => p.StartWith(AutoSuggestBox.Text)).ToArray();
7    autoSuggestBox.ItemSource = filtered;
8}

投影(转换)运算符 Select

以下的例子展示了如何用select修改输入的元素序列。

1int[] numbers = {5,4,1,3,9,8,6,7,2,0};
2
3var numsPlusOne = from n in numbers
4                  select n+1;

选择一个单独的属性

1var productNames = from p in products
2                   select p.ProductName; // 选择了p的ProductName属性

select进行一些变换

1int[] numbers = {5,4,1,3,9,8,6,7,2,0}; // 数字序列
2string[] strings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; // 单词序列
3
4var textNums = from n in numbers
5               select strings[n]; // 用数字序列的元素作为下标选择单词序列中的元素

选择匿名类型或元组

注意:创建新类型的时候,需要使用new关键字

1string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
2
3var upperLowerWords = from w in words
4                      select new { Upper = w.ToUpper(), Lower = w.ToLower() };
5                      // 生成的Upper和Lower里面分别是这些单词的大写和小写版本
6
7// 使用元组的方法(从C#7开始)
8var upperLowerWords = from w in words
9                      select new { Upper: w.ToUpper(), Lower: w.ToLower() };

使用select创建新类型

1int[] numbers = {5,4,1,3,9,8,6,7,2,0}; // 数字序列
2string[] strings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; // 单词序列
3
4var digitOddEvens = from n in numbers
5                    select new { Digit = strings[n], Even = (n % 2 == 0)}; 
6                    // 创建了两个类型:
7                    //  Digit:对应数字的单词序列
8                    //  Even:偶数序列

选择属性的子集 我还没试,Try.NET坏了…😭

1var productInfos = from p in products
2                   select (p.ProductName, p.Category, Price: p.UnitPrice);
3
4Console.WriteLine("Product Info:");
5foreach (var productInfo in productInfos)
6{
7    Console.WriteLine($"{productInfo.ProductName} is in the category {productInfo.Category} and costs {productInfo.Price} per unit.");
8}

用元素的index对其进行选择

1int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
2var numsInPlace = numbers.Select((num, index) => (Num: num, InPlace: (num == index)));
3// 得到的numsInPlace中有Num和InPlace,其中InPlace为num==index的值

在多输入序列中进行选择

 1int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
 2int[] numbersB = { 1, 3, 5, 7, 8 };
 3
 4var pairs = from a in numbersA
 5            from b in numbersB
 6            where a < b
 7            select (a, b); // 符合条件的(a,b)对(pairs)
 8
 9Console.WriteLine("Pairs where a < b:");
10foreach (var pair in pairs)
11{
12    Console.WriteLine($"{pair.a} is less than {pair.b}");
13    // 把所有的a和所有的b逐个进行比较
14}

在相关的输入序列中进行选择

1var orders = from c in customers
2             from o in c.Orders
3             where o.Total < 500.00M
4             select (c.CustomerID, o.OrderID, o.Total);
5             // cutomers -> c:顾客
6             // c -> c.o:订单(与c相关联)
7             // c.o -> o:订单信息

带有Where的符合选择

1var orders = from c in customers
2             from o in c.Orders
3             where o.OrderDate >= new DateTime(1998, 1, 1)
4             select (c.CustomerID, o.OrderID, o.OrderDate);

Query Syntax 查询语法(分区运算符)

Take

n.Take(n);获取前n个元素

1int[] numbers={5,4,3,2,1};
2var first3Numbers = numbers.Take(3); // First3Numbers是一个集合,有3个数

Take也可以嵌套到其它查询语句中

1var first3WAOrders = (
2	from customer in customers
3	from order in cutomer.Orders
4	where customer.Region == "WA"
5	select (customer.CustomerID, order.OrderID, order.OrderDate)
6	.Take(3);
7) // 得到前3个

Skip

n.Skip(n)跳过前n个元素

1int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
2var allButFirst4Numbers = numbers.Skip(4);

先查询,再在结果中跳过

1var waOrders = from cust in customers
2               from order in cust.Orders
3               where cust.Region == "WA"
4               select (cust.CustomerID, order.OrderID, order.OrderDate);
5
6var allButFirst2Orders = waOrders.Skip(2); // 查询完毕后,从查询结果中跳过前2个结果

TakeWhile

理解为While循环下的Take()。一旦不符合条件就停止。

1int[] numbers = {5,4,1,3,9,8,6,7,2,0};
2var firstNumbersLessThan6 = numbers.TakeWhile(n => n<6);
3                        // 从开始一直Take(),直到n<6的条件不成立

index作为条件的TakeWhile

1int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
2var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);

SkipWhile

以下例子只显示分数小于80的成绩。

 1int[] grades = { 59, 82, 70, 56, 92, 98, 85 };
 2
 3IEnumerable<int> lowerGrades =
 4    grades
 5    .OrderByDescending(grade => grade)
 6    .SkipWhile(grade => grade >= 80);
 7
 8Console.WriteLine("All grades below 80:");
 9foreach (int grade in lowerGrades)
10{
11    Console.WriteLine(grade);
12}
13
14// This code produces the following output:
15
16// All grades below 80:
17// 70
18// 59
19// 56

使用nindex进行筛选

 1int[] amounts = { 5000, 2500, 9000, 8000,
 2                    6500, 4000, 1500, 5500 };
 3
 4IEnumerable<int> query =
 5    amounts.SkipWhile((amount, index) => amount > index * 1000);
 6
 7foreach (int amount in query)
 8{
 9    Console.WriteLine(amount);
10}
11
12
13// This code produces the following output:
14
15// 4000
16// 1500
17// 5500

排序运算符

orderby 升序

升序:0,1,2,… 使用orderby根据宠物年龄进行升序排序

 1class Pet
 2{
 3    public string Name { get; set; }
 4    public int Age { get; set; }
 5}
 6
 7public static void OrderByEx1()
 8{
 9    Pet[] pets = { new Pet { Name="Barley", Age=8 },
10                   new Pet { Name="Boots", Age=4 },
11                   new Pet { Name="Whiskers", Age=1 } };
12
13    // Sort the Pet objects in the array by Pet.Age.
14    IEnumerable<Pet> query =
15        pets.AsQueryable().OrderBy(pet => pet.Age);
16
17    foreach (Pet pet in query)
18        Console.WriteLine($"{pet.Name} - {pet.Age}");
19}
20
21// This code produces the following output:
22
23// Whiskers - 1
24// Boots - 4
25// Barley - 8

orderby descending

使用orderbydescending关键字对数字进行降序排序。

1double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
2
3var sortedDoubles = from d in doubles
4                    orderby d descending // 注意descending的用法
5                    select d;
6
7Console.WriteLine("The doubles from highest to lowest:");

序列操作

EqualAll

如果两个序列相同,返回True

1var wordsA = new string[] { "cherry", "apple", "blueberry" };
2var wordsB = new string[] { "cherry", "apple", "blueberry" };
3
4bool match = wordsA.SequenceEqual(wordsB);
5
6Console.WriteLine($"The sequences match: {match}"); //True
7// 如果以上两个序列中的元素顺序进行了调换,输出值则为False

Zip

1int[] vectorA = { 0, 2, 4, 5, 6 };
2int[] vectorB = { 1, 3, 5, 7, 8 };
3
4int dotProduct = vectorA.Zip(vectorB, (a, b) => a * b).Sum();
5                            // 把A中的元素和B中的对应元素进行操作。
6                            // Sum()为求和
7
8Console.WriteLine($"Dot product: {dotProduct}");
9// Dot product:109

Query(查询)执行模式

懒惰执行

如果数据经常变化,可以考虑使用“懒惰查询”,需要时再进行查询。

 1int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
 2
 3int i = 0;
 4var q = from n in numbers
 5        select ++i; //i: 0 → 1
 6
 7// Note, the local variable 'i' is not incremented
 8// until each element is evaluated (as a side-effect):
 9// 直到每个值被使用时才执行++i
10foreach (var v in q)
11{
12    Console.WriteLine($"v = {v}, i = {i}");
13    // ++i在这里才被执行并存入v中。
14    // 这里的i是原来的i(int i=0时定义的)
15}

如果把foreach再完整执行一遍,vi的值将会到达20

急迫执行

当数据不会变时使用“急迫执行”,因为再次查询数据也不会变。

 1// Methods like ToList() cause the query to be
 2// executed immediately, caching the results.
 3// 类似ToList()的方法可以使query立即执行。
 4
 5int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
 6
 7int i = 0;
 8var q = (from n in numbers
 9         select ++i)
10         .ToList();
11
12// The local variable i has already been fully
13// incremented before we iterate the results:
14// 在输出结果之前,++i已经全部执行完了
15foreach (var v in q)
16{
17    Console.WriteLine($"v = {v}, i = {i}");
18}

如果把foreach再完整执行一遍,i的值仍然全为10,v的值也不变

huuhghhgyg

Writter by : huuhghhgyg

Never Settle

Recommended for You

正则表达式笔记

正则表达式笔记

FileGetter使用说明

FileGetter使用说明