Bladeren bron

Linq

master
QYYEE 5 jaren geleden
bovenliggende
commit
2d0a65f579
3 gewijzigde bestanden met toevoegingen van 157 en 74 verwijderingen
  1. 26
    1
      实践/后端/C#基础/26.字典.md
  2. 0
    73
      实践/后端/C#基础/7.C#中的Linq.md
  3. 131
    0
      实践/后端/C#基础/7.Linq.md

+ 26
- 1
实践/后端/C#基础/26.字典.md Bestand weergeven

@@ -139,4 +139,29 @@ while (true)
139 139
         WriteLine(ex.Message);
140 140
     }
141 141
 }
142
-```
142
+```
143
+
144
+> Lookup类
145
+- Dictionary<TKey,TValue>类支持每个键关联一个值。Lookup<TKey,TElement>类非常类似于Dictionary<TKey,TValue>类,但把键映射到一个值集合上。这个类在程序集System.Core中实现,用System.Linq名称空间定义。
146
+- Lookup<TKey,TElement>类不能像一般的字典那样创建,而必须调用ToLookup()方法,该方法返回一个Lookup<TKey,TElement>对象。ToLookup()方法是一个扩展方法,它用于实现IEnumberable<T>接口的所有类。
147
+- 下面例子中,填充一个Racer对象列表。因为List<T>类实现了IEnumberable<T>接口,所以可以在赛车手列表上调用ToLookup()方法。这个方法需要一个Func<TSource,Tkey>类的委托,Func<TSource,TKey>类定义了键的选择器。
148
+```
149
+var racers=new List<Racer>();
150
+racers.Add(new Racer("Jacques","Villeneuve","Canada",11));
151
+racers.Add(new Racer("Alan","Jones","Australia",12));
152
+racers.Add(new Racer("Jackie","Stewart","United Kingdom",27));
153
+racers.Add(new Racer("James","Hunt","United Kingdom",10));
154
+racers.Add(new Racer("Jack","Brabham","Australia",14));
155
+
156
+var lookupRacers=racers.ToLookup(r=>r.Country);
157
+foreach (Racer r in lookupRacers("Australia"))
158
+{
159
+    WriteLine(r);
160
+}
161
+```
162
+> 有序字典
163
+- SortedDictionary<TKey,TValue>是一个二叉搜索树,其中的元素根据键来排序。该键类型必须实现IComparablc<TKey>接口。如果键的类型不能排序,则还可以创建一个实现了IComparer<TKey>接口的比较器,将比较器用作有序字典的构造函数的一个参数。
164
+- SortedDictionary<TKey,TValue>和SortedList<TKey,TValue>的功能类似。但因为SortedList<TKey,TValue>实现为一个基于数组的列表,而SortedDictionary<TKey,TValue>类实现为一个字典。他们有不同的特征。
165
+    - SortedList<TKey,TValue>使用的内存比SortedDictionary<TKey,TValue>少。
166
+    - SortedDictionary<TKey,TValue>的元素插入和删除操作比较快。
167
+    - 在用已排好序的数据填充集合时,若不需要修改容量,SortedList<TKey,TValue>比较快

+ 0
- 73
实践/后端/C#基础/7.C#中的Linq.md Bestand weergeven

@@ -1,73 +0,0 @@
1
-> Linq语句
2
-
3
-其实Linq语句本质上是对实现了IEnumerable的接口的对象进行操作,而所有的数组和集合都实现了这个接口。
4
-
5
-> Linq常用的方法。
6
-- where
7
-   - where用于筛选数据源中的元素,只要给他指定数据源中的子元素的任意布尔值类型的表达式就可以了。
8
-   -  where不是必须Linq使用里面必须指定的选项,但一般都要用到。
9
-- orderby
10
-   - 类似于SQL,在对数据进行筛选之后,我们还可以进一步地对数据进行排序。
11
-   - 如果是倒叙排列,则需要在后面加descending。
12
-- 聚合函数
13
-   - 和SQL一样,Linq也有Max(),Min(),Count(),Sum(),Average()这些聚合函数,继续沿用上面的学生对象例子,聚合函数需要在Linq表达式之后输出使用。
14
-- select
15
-   - select可以用以指定查询的具体字段
16
-- Take和Skip
17
-   - Take和Skip可以用以进行前几个数据的筛选
18
-   - Take用来表明获取几个的数据,Skip用来省略前几项的数据,指偏移量
19
-```
20
-//取出成绩最高的三位学生
21
-var result = (from s in students
22
-             orderby s.source descending
23
-             select s.source).Take(3);
24
-//根据id查出学生信息,每页显示5个,当前是第2页
25
-var result = (from s in students
26
-             orderby s.id
27
-             select s.source).Skip(1*5).Take(5);
28
-```
29
-
30
-- Distinct 
31
-  
32
-  这个方法将从序列(集合)中返回去重复(Distinct)元素
33
-  
34
-- First 
35
-  
36
-   这个方法会返回序列中的第一个元素
37
-  
38
-- All 
39
-  
40
-这个方法确定是否所有元素序列都满足某种条件
41
-- Any 
42
-
43
-这个方法确定序列中的元素是否存在或者满足某种特定的条件
44
-
45
-- Average 
46
-  
47
-Average方法会计算在序列中的数字的平均值
48
-
49
-- Concat 
50
-
51
-这个方法的作用是连接(拼接)两个序列.这个方法通过"延迟执行"(deferred execution)来执行.它的返回值是包含需要执行特定操作所有信息的迭代器类型的一种实例
52
-
53
-- Contains 
54
-
55
-这个方法用来判断在一个序列(集合)中是否存在一个特殊的元素.这个方法有两种重载方式,第一种是通过默认的比较器来判断序列(集合)中是否有特殊的元素,另外一种是通过自定义
56
-- First 
57
- 
58
- 返回集合中的第一个元素;不延迟
59
-
60
-- FirstOrDefault 
61
-  
62
-  返回集合中的第一个元素(如果没有则返回默认值);
63
-
64
-- ToDictionary 
65
-  
66
- 将集合转换为<K, V>集合;
67
-
68
-- ToList 
69
-  
70
-  将集合转换为List<T>集合
71
-- ToArray 
72
-
73
-将集合转换为数组

+ 131
- 0
实践/后端/C#基础/7.Linq.md Bestand weergeven

@@ -0,0 +1,131 @@
1
+> Linq概述
2
+- Linq(语言集成查询)在C#中集成了查询语法,可以用相同的语法访问不同的数据源。Linq提供了不同数据源的抽象层,所以可以使用相同的语法。
3
+  
4
+
5
+> 标准的查询操作符
6
+- Where   OffType<TResult>
7
+   - 筛选操作符定义了返回元素的条件。在Where查询操作符中可以使用谓词。例如,lambda表达式定义的谓词,来返回布尔值。OfType<TResult>根据类型筛选元素,只返回TResult类型的元素
8
+- Select  SelectMany
9
+    - 投射操作符用于把对象转换为另一个类型的新对象。Select和SelectMany定义了根据选择器函数选择结果值得投射
10
+- OrderBy\ThenBy\OrderByDescending\ThenByDescending\ThenByDescending\Reverse
11
+  - 排序操作符改变所返回的元素的顺序。OrderBy按升序排序,OrderByDescending按降序排序。如果第一次排序的结果很类似,就可以使用ThenBy和ThenBy Deacending 操作符进行第二次排序。Reverse反转集合中元素的顺序
12
+    
13
+- Join\GroupJoin
14
+   -连接操作符用于合并并不直接相关的集合。使用Join操作符,可以根据键选择器函数连接两个集合,这个类似于SQL中的JOIN。GroupJoin操作符连接两个集合,组合其结果
15
+
16
+- GroupBy\ToLookup
17
+    - 组合操作符把数据放在组中。GroupBy操作符组合有公共键的元素。ToLookup通过创建一个一对多字典,来组合元素
18
+
19
+- Any\All\Contains
20
+    - 如果元素序列满足指定的条件,限定符操作符就返回布尔值。Any确定集合中是否有满足为此函数的元素;All确定集合中的所有元素是否都满足谓词函数;Contains检查某个元素是否在集合中
21
+
22
+- Take\Skip\TakeWhile\SkipWhile
23
+    - 分区操作符返回集合的一个子集。Take、Skip、TakeWhile和SkipWhile都是分区操作符。使用它们可以得到部分结果。使用Take必须指定要从集合中提取的元素个数;Skip跳过指定的元素个数,提取其他元素;TakeWhile提取条件为真的元素,SkipWhile跳过条件为真的元素。
24
+
25
+- Distinct\Union\Intersect\Except\Zip
26
+    - Set操作符返回一个集合。Distinct从集合中删除重复的元素,除了Distinct之外,其他Set操作符都需要两个集合。Union返回出现在其中一个集合中的唯一元素。Intersect返回两个集合中都有的元素。Except返回只出现在一个集合中的元素。Zip把两个集合合并为一个。
27
+
28
+- First\FirstOrDefault\Last\LastOrDefault\ElementAt\ElementAtOrDefault\Single\SingleOrDefault
29
+    - 这些元素操作符仅返回一个元素。First返回第一个满足条件的元素。FirstOrDefault类似于First,但如果没有找到满足条件的元素,就返回类型的默认值。Last返回最后一个满足条件的元素。ElemAt指定了要返回的元素的位置。Single只返回一个满足条件的元素。如果有多个元素都满足条件,就抛出一个异常。所有的XXOrDefault方法都类似与以相同前缀开头的方法,但如果没有找到该元素,他们就返回类型的默认值
30
+
31
+- Count\Sum\Min\Max\Average\Aggregate
32
+    - 聚合操作符计算集合的一个值。利用这些聚合操作福,可以计算所有值得总和、所有元素的个数、值最大和最小的元素,以及平均值等
33
+
34
+- ToArray\AsEnumerable\ToList\ToDictionary\Cast<TResult>
35
+    - 这些转换操作符将集合转换为数组:IEnumerable、IList、IDictionary等。Cast方法把集合的每个元素类型转换为泛型参数类型
36
+
37
+- Empty\Range\Repeat
38
+    - 这些生成操作符返回一个心机和。使用Empty时集合时空的:Range返回一系列数字:Repeat返回一个始终重复一个值得集合
39
+
40
+
41
+**筛选**
42
+- 使用where子句,可以合并多个表达式。例如,找出赢得至少15场比赛的巴西和奥地利赛车手。
43
+```
44
+var racers = from r in Formulal.GetChampions()where r.Wins> 15 &&(r.Country=="Brazil" || r.Country="Austria") select r;
45
+
46
+foreach(var r in rqacers)
47
+{
48
+    WriteLine($"{r:A}");
49
+}
50
+
51
+var racers=Formulal.GetChampions().Where(r=>r.Wins>15 &&(r.Country=="Brazil" || r.Country== "Austria")).Select(r=>r);
52
+```
53
+> 用索引筛选
54
+- 不能使用Linq查询的一个例子是Where()方法的重载。在Where()方法的重载中,可以传递第二个参数--索引。索引是筛选器返回的每个结果的计数器。可以在表达式中使用这个索引,执行基于索引的计算。
55
+```
56
+var racers =Formulal.GetChamplons().Where((r,index)=>r.LastName.StartsWith("A") && index%2!=0);
57
+foreach (var r in racers)
58
+{
59
+    WriteLine(${r:A});
60
+}
61
+```
62
+
63
+> 类型筛选
64
+
65
+-为了基于类型的筛选,可以使用OfType()扩展方法。这里数组数据包含string和int对象。使用OfType()扩展方法,把string类传送给泛型参数,就从集合中仅返回字符串
66
+```
67
+object[] data={"one",2,3,"four","five",6};
68
+var query=data.OfType<string>();
69
+foreach(var s in query)
70
+{
71
+ WriteLine(s);   
72
+}
73
+```
74
+
75
+
76
+> LINQ查询中的变量
77
+
78
+- 在为分组编写的LINQ查询中,Count方法调用了多次。使用了let子句可以改变这种方式。let允许在LINQ查询中定义变量:
79
+```
80
+var countries=Formulal.GetChampions().GroupBy(r=>r.Country).Select(g=>new{Group=g,Count=g.Count()}).OrderByDescending(g=>g.Count).ThenBy(g=>g.Group.Key).Where(g=>g.Count>=2).Select(g=>new
81
+{
82
+    Country=g.Group.Key,
83
+    Count=g.Count
84
+});
85
+```
86
+
87
+> 内连接
88
+- 使用join子句可以根据特定的条件合并两个数据源,但之前要获得两个要连接的列表。
89
+- 例子:在一级方程式比赛中,有赛车手冠军和车队冠军。赛车手从GetChampions()方法中返回,车队从GetConstructorChampions()方法中返回。现在要获得一个年份表,列出每年的赛车手冠军和车队冠军
90
+    - 先定义两个查询,用于查询赛车手和车队
91
+     ```
92
+     var racers=from r in Formulal.GetChampions() from y in r.Years select new
93
+     {
94
+         Year=y,
95
+         Name=r.FirstName+""+r.LastName
96
+     };
97
+     var teams=from t in Formulal.GetContructorChampions() from y in t.Years select new
98
+     {
99
+         Year =y,
100
+         Name=t.Name
101
+     };
102
+     ```
103
+    - 有了这两个查询,再通过join子句,根据赛车手获得冠军的年份和车队获得冠军的年年份进行连接。select子句定义了一个新的匿名类型,它包含Year、Racer和Team属性。
104
+     ```
105
+     var racersAndTeams=(from r in racers join t in teams on r.Year equals t.Year select new
106
+     {
107
+         r.Year,
108
+         Champion=r.Name,
109
+         Constructor=t.Name
110
+     }).Take(10);
111
+     WriteLine("Year World Champion\t Constructor Title");
112
+     foreach (var item in racersAndTeams)
113
+     {
114
+         WriteLine($"{item.Year}:{item.Champion,-20}{item.Constructor}");
115
+     }
116
+     也可以把它们合并为一个LINQ查询
117
+     var racersAndTeams=
118
+     {
119
+         from r in 
120
+         from r1 in Formulal.GetChampions()
121
+         from yr in r1.Years
122
+         select new
123
+         {
124
+             Year=yr,
125
+             Name=r1.FirstName + "" +r1.LastName
126
+         }
127
+         join t in
128
+         from t1 in Formulal.GetContructorChampios
129
+
130
+     }
131
+     ```

Laden…
Annuleren
Opslaan