LINQ函數雖然和LINQ語句實現了一樣的功能,但LINQ函數使用起來更加快捷。學過數據庫的感受LINQ語句都不難,但語句比較長。數據庫
會LINQ函數,纔算會LINQ。api
一、Where(),結果過濾函數
1 List<int> list = new List<int>() {1,2,3,4,5,6,7,8,9,10 }; 2 IEnumerable<int> newList = list.Where(a => a >= 3); 3 //查找大於3的數 4 //輸出 5 foreach (var item in newList) 6 { 7 Console.WriteLine(item); 8 }
結果:oop
3
4
5
6
7
8
9
10測試
二、Select()ui
Select()處理結果會傳回一個對象,這個對象能夠是如今對象 ,也能夠是匿名類型。spa
在LINQ語句 中的select new語句 ,會自動被編譯器轉換爲Select().code
有以下代碼:對象
1 List<int> list = new List<int>() {1,2,3,4,5,6,7,8,9,10 }; 2 var Num = from aa in list 3 where aa == 1 4 select new 5 { 6 Number = aa, 7 }; 8 Console.WriteLine(Num.FirstOrDefault().Number);
1 var SelectNum = list.Where(x => x == 1).Select(x => new 2 { 3 Number = x 4 });
上面兩段代碼實際上是同樣的。blog
三、SelectMany()
SelectMany()相似於數據庫中的CrossJoin
1 List<int> list1 = new List<int>() { 1, 2, 3, 4, 5, 6 }; 2 List<int> list2 = new List<int>() { 6, 4, 2, 7, 9, 0 };
1 var query = list1.SelectMany(x => list2); 2 foreach (var item in query) 3 { 4 Console.WriteLine(item); 5 }
運行結果就是將list2輸出6次
下面來看看MSDN上面的代碼
class PetOwner { public string Name { get; set; } public List<String> Pets { get; set; } } public static void SelectManyEx1() { PetOwner[] petOwners = { new PetOwner { Name="Higa, Sidney", Pets = new List<string>{ "Scruffy", "Sam" } }, new PetOwner { Name="Ashkenazi, Ronen", Pets = new List<string>{ "Walker", "Sugar" } }, new PetOwner { Name="Price, Vernette", Pets = new List<string>{ "Scratches", "Diesel" } } }; // Query using SelectMany(). IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets); Console.WriteLine("Using SelectMany():"); // Only one foreach loop is required to iterate // through the results since it is a // one-dimensional collection. foreach (string pet in query1) { Console.WriteLine(pet); } }
運行結果:
Using SelectMany():
Scruffy
Sam
Walker
Sugar
Scratches
Diesel
這裏其實很好理解 。就是1對2,輸出2.
四、GroupBy()
GroupBy()會按照給定的key(keySelector)以及內容elementSelector,產生羣組後的結果
GroupBy()設置了使用數列自己做爲Key值,而且利用這個Key分組產生分組的數據。
1 List<int> list = new List<int>() { 1, 2, 3, 4, 5, 1, 5 }; 2 3 var query = list.GroupBy(x => x); 4 5 foreach (var item in query) 6 { 7 Console.WriteLine("NUMBER:{0} COUNT{1}",item.Key,item.Count()); 8 }
運行結果:
NUMBER:1 COUNT2
NUMBER:2 COUNT1
NUMBER:3 COUNT1
NUMBER:4 COUNT1
NUMBER:5 COUNT2
1 foreach (var item in query) 2 { 3 for (int i = 0; i < item.Count(); i++) 4 { 5 Console.WriteLine(item.ElementAt(i)); 6 } 7 Console.WriteLine("======================="); 8 }
運行結果:
1
1
=======================
2
=======================
3
=======================
4
=======================
5
5
=======================
五、ToLookUp()
從 IEnumerable<T> 生成一個泛型 Lookup<TKey, TElement>。
ToLookUp()看起來和GroupBy()有些相似,可是它會另外生成一個新的集合對象,這個集合對象由ILookup<TKey,TElement>組成
1 var Marks = new[] 2 { 3 new {Mark = 90,Group = "A"}, 4 new {Mark = 80,Group = "B"}, 5 new {Mark = 70,Group = "C"}, 6 new {Mark = 60,Group = "D"} 7 }; 8 9 var lookUpValue = Marks.ToLookup(x => x.Group); 10 11 foreach (var item in lookUpValue) 12 { 13 Console.WriteLine("========Group:{0}=============",item.Key); 14 foreach (var result in item) 15 { 16 Console.WriteLine(result.Group + " " + result.Mark); 17 } 18 }
運行結果
========Group:A=============
A 90
========Group:B=============
B 80
========Group:C=============
C 70
========Group:D=============
D 60
另外一段測試代碼:
1 var MarksWithName = new[] 2 { 3 new {Mark = 90,Name="Jack",Group="A"}, 4 new {Mark = 80,Name="Jany",Group="B"}, 5 new {Mark = 70,Name = "Tom",Group="C"} 6 }; 7 8 var lookUpValue2 = MarksWithName.ToLookup(x => x.Group); 9 foreach (var item in lookUpValue2) 10 { 11 Console.WriteLine("============Group:{0}==============",item.Key); 12 foreach (var result in item) 13 { 14 Console.WriteLine("Name:{0} Mark:{1}",result.Name,result.Mark); 15 } 16 }
運行結果:
============Group:A==============
Name:Jack Mark:90
============Group:B==============
Name:Jany Mark:80
============Group:C==============
六、Join
將兩個集合進行聯接,即數據庫中的Inner Join
1 var Mark = new[] 2 { 3 new {Name = "C",Mark = 65}, 4 new {Name = "A",Mark = 70}, 5 new {Name = "B", Mark = 80} 6 7 }; 8 9 var Age = new[] 10 { 11 new {Name = "B",Age = 18}, 12 new {Name = "C",Age = 17}, 13 new {Name = "A",Age = 20} 14 };
//LINQ語句 var query = from mk in Mark join ae in Age on mk.Name equals ae.Name select new { Name = mk.Name, Mark = mk.Mark, Age = ae.Age }; //輸出 foreach (var item in query) { Console.WriteLine("姓名{0} 成績{1} 年齡{2}",item.Name,item.Mark,item.Age); }
1 //LINQ函數 2 3 var query2 = Mark.Join(Age, mk => mk.Name, ae => ae.Name, (mk, ae) => new { Name = mk.Name,Mark = mk.Mark,Age = ae.Age }); 4 5 foreach (var item in query2) 6 { 7 Console.WriteLine("姓名{0} 成績{1} 年齡{2}", item.Name, item.Mark, item.Age); 8 }
上面兩段代碼輸出的結果都是:
姓名C 成績65 年齡17
姓名A 成績70 年齡20
姓名B 成績80 年齡18
七、GroupJoin
將兩個集合進行聯接,並對結果進行分組。下面的例子就是以國家名字爲組,顯示其對應的省份信息。
1 class Country 2 { 3 public string CountryName { get; set; } 4 } 5 6 class Province 7 { 8 public Country OwnerCountry { get; set; } 9 public string ProvinceName { get; set; } 10 public string ProvinceSize { get; set; } 11 public string ProvinceSpot { get; set; } 12 }
1 Country c1 = new Country() 2 { 3 CountryName = "China" 4 }; 5 6 Country c2 = new Country() 7 { 8 CountryName = "America" 9 }; 10 11 Country c3 = new Country() 12 { 13 CountryName = "Korea" 14 }; 15 16 Country c4 = new Country() 17 { 18 CountryName = "Russian" 19 }; 20 21 22 Province p1 = new Province() 23 { 24 ProvinceName = "Hunan", 25 ProvinceSize = "200", 26 ProvinceSpot = "Old City", 27 OwnerCountry = c1 28 }; 29 30 Province p2 = new Province() 31 { 32 ProvinceName = "Chicago", 33 ProvinceSize = "150", 34 ProvinceSpot = "Linkin Park", 35 OwnerCountry = c2 36 }; 37 38 Province p3 = new Province() 39 { 40 ProvinceName = "Seoul", 41 ProvinceSize = "100", 42 ProvinceSpot = "Tian Tian World", 43 OwnerCountry = c3, 44 }; 45 46 Province p4 = new Province() 47 { 48 ProvinceName = "Hunan", 49 ProvinceSize = "200", 50 ProvinceSpot = "Tian Meng Mountain", 51 OwnerCountry = c1 52 }; 53 54 Province p5 = new Province() 55 { 56 ProvinceName = "Moscow", 57 ProvinceSize = "80", 58 ProvinceSpot = "Moscow University", 59 OwnerCountry = c4 60 }; 61 62 Province p6 = new Province() 63 { 64 ProvinceName = "Moscow", 65 ProvinceSize = "80", 66 ProvinceSpot = "HelloWorld", 67 OwnerCountry = c4 68 };
聲明4個Country類和6個Province類,並放入countries和provinces集合
1 List<Province> provinces = new List<Province>() 2 { 3 p1,p2,p3,p4,p5,p6 4 }; 5 6 List<Country> countries = new List<Country>() 7 { 8 c1,c2,c3,c4 9 };
先來看看Join的結果
1 var joinResult = countries.Join(provinces, 2 country => country, 3 province => province.OwnerCountry, 4 (country, province) => 5 new 6 { 7 CountryName = country.CountryName, 8 ProvinceName = province.ProvinceName, 9 Size = province.ProvinceSize, 10 Spot = province.ProvinceSpot, 11 }); 12 Console.WriteLine("--------------------------------"); 13 foreach (var item in joinResult) 14 { 15 Console.WriteLine(item.CountryName + " " + item.ProvinceName + " " + item.Size + " " + item.Spot); 16 }
運行結果:
--------------------------------
China Hunan 200 Old City
China Hunan 200 Tian Meng Mountain
America Chicago 150 Linkin Park
Korea Seoul 100 Tian Tian World
Russian Moscow 80 Moscow University
Russian Moscow 80 HelloWorld
--------------------------------
再看看GroupJoin的結果
1 var groupJoinResult = countries.GroupJoin(provinces, 2 country=>country, 3 province=>province.OwnerCountry, 4 (country,province)=> 5 new 6 { 7 Name = country.CountryName, 8 ProvinceSet = province.Select(x=>x) 9 }); 10 foreach (var item in groupJoinResult) 11 { 12 Console.WriteLine("******************"); 13 Console.WriteLine(item.Name); 14 foreach (var p in item.ProvinceSet) 15 { 16 Console.WriteLine(p.ProvinceName + " " + p.ProvinceSize + " " + p.ProvinceSpot); 17 } 18 }
運行結果:
******************
China
Hunan 200 Old City
Hunan 200 Tian Meng Mountain
******************
America
Chicago 150 Linkin Park
******************
Korea
Seoul 100 Tian Tian World
******************
Russian
Moscow 80 Moscow University
Moscow 80 HelloWorld
8、Distinct
去除集合中的重複結果
值類型
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 List<int> valueList = new List<int>() { 1, 1, 2, 2, 3, 3, 4, 4, }; 6 var distinctValueList = valueList.Distinct().ToList(); 7 distinctValueList.ForEach(x => Console.WriteLine(x)); 8 } 9 }
運行結果
1
2
3
4
引用類型
1 public class PrintImage 2 { 3 public int ImageKey { get; set; } 4 5 public string ImagePath { get; set; } 6 } 7 8 //定義方法以支持對象的相等比較。 9 //https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.iequalitycomparer-1?redirectedfrom=MSDN&view=netframework-4.8 10 class PrintImageEqualityComparer : IEqualityComparer<PrintImage> 11 { 12 public bool Equals(PrintImage p1, PrintImage p2) 13 { 14 if (p1 == null && p2 == null) 15 return true; 16 else if (p1 == null || p2 == null) 17 return false; 18 else if (p1.ImageKey == p2.ImageKey) 19 return true; 20 else 21 return false; 22 } 23 24 public int GetHashCode(PrintImage pImage) 25 { 26 return pImage.ImageKey.GetHashCode(); 27 } 28 } 29 30 class Program 31 { 32 static void Main(string[] args) 33 { 34 List<PrintImage> objList = new List<PrintImage>() 35 { 36 new PrintImage() 37 { 38 ImageKey = 1, 39 ImagePath = "D:\\crawler\\image1" 40 }, 41 new PrintImage() 42 { 43 ImageKey = 1, 44 ImagePath = "D:\\crawler\\image2" 45 }, 46 new PrintImage() 47 { 48 ImageKey = 2, 49 ImagePath = "D:\\crawler\\image3" 50 }, 51 new PrintImage() 52 { 53 ImageKey = 3, 54 ImagePath = "D:\\crawler\\image4" 55 } 56 }; 57 58 //使用實現了IEqualityComparer<T>的PrintImageEqualityComparer類對PrintImage對象進行比較 59 //經過使用Distincet去除了集合中的第二個對象 60 var distinctObjList = objList.Distinct(new PrintImageEqualityComparer()).ToList(); 61 distinctObjList.ForEach(x => { Console.WriteLine(x.ImageKey); Console.WriteLine(x.ImagePath); }); 62 } 63 }
運行結果:
1
D:\crawler\image1
2
D:\crawler\image3
3
D:\crawler\image4