助力快速理解 SelectMany 具體用途,4重載分析 爲初學者節省寶貴的時間,避免採坑! |
我們的初衷是將一種簡單的生活方式帶給世人 使有限時間 具備無限可能 |
Chinar 教程效果:
----------
文章目錄
1 Intro —— 簡介
Select
非常簡單,將序列中選定的類型,返回一個新的集合
SelectMany
如其字面意思:選擇許多就是在 Select 的基礎上,同時選定多個,返回多個而已
但 SelectMany
很多初學者並非完全理解,致使其使用率不高。
其實SelectMany
是一個非常實用的功能,可大量減少我們的代碼量。
對數據進行查詢時,可同時返回多項自定義類型,對數據的可控性非常高。
光說概念,呲牛逼。這顯然不是 我 Chinar 的教程風格。
2 Data —— 數據類
爲了便於理解,先來一個數據類。下邊幾個重載,都用這一個數據進行說明
通用數據類
爲避免初學者,被循環給繞暈
這裏命名方式採用A B C 、One Two Three
便於區分。 層級由外到內
one 第一層 ---------- A1
two 第二層 ---------- A2
three 第三層 ----------
數據類
/// <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}";
}
}
添加數據信息
List<One> ones = new List<One> //第一層:列表
{
new One("A1", 40, new List<Two> //第二層:0
{
new Two("A2_0", 20, new List<Three> {new Three(10, 100)}), //第三層
new Two("A2_1", 200, new List<Three> {new Three(10, 100)}), //第三層
new Two("A2_2", 2000, new List<Three> {new Three(10, 100)}) //第三層
}),
new One("B1", 50, new List<Two>//第二層:1
{
new Two("B2", 30, new List<Three> {new Three(14, 70)})
}),
new One("C1", 70, new List<Two>//第二層:2
{
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>//第二層:3
{
new Two("D2", 60, new List<Three> {new Three(40, 50)})
}),
};
3 Parameter 1 —— 重載1:1個參數
別看很複雜的樣子,其實要點是:對 IEnumerable source,
接口類型, 擴展函數/方法
IEnumerable SelectMany<TSource, TResult>(this IEnumerable source,
Func<TSource, IEnumerable<TResult>> selector
);
傳入參數爲:一個 Func 委託類型
對數據源
TSource
處理,返回一個IEnumerable <TResult >
集合
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
}
打印輸出
4 Parameter 2 —— 重載2:2個參數
別看很複雜的樣子,其實要點是:對 IEnumerable source,
接口類型, 擴展函數/方法
IEnumerable SelectMany<TSource, TResult>(this IEnumerable source,
Func<TSource, IEnumerable<TResult>> selector
);
傳入參數爲:一個 Func 委託類型
對數據源
TSource
處理,返回一個IEnumerable <TResult >
集合
#region 重載 2
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
#region 重載 3
Console.WriteLine("----------重載 三 ------------");
var onesSelectMany3 = ones.SelectMany(one => one.TwoList, (one, two) => new {one.Name, two.Age}); //返回匿名類型: 1級的名字,2級的年齡
//var onesSelectMany3 = ones.SelectMany(one => one.TwoList, (one, two) => new Dictionary<string, int> {{ one.Name, two.Age } });//可自定義返回類型
foreach (var v in onesSelectMany3)
{
Console.WriteLine(v); //v=匿名類型
}
#endregion
#region 重載 4
Console.WriteLine("----------重載 三 ------------");
var onesSelectMany4 = ones.SelectMany((one, index) => one.TwoList.Select(_ => "索引:" + index + "--名字:" + _.Name), (one, two) => new {one.Name, two}); //返回匿名類型: 1級的名字,2級的年齡
//var onesSelectMany3 = ones.SelectMany(one => one.TwoList, (one, two) => new Dictionary<string, int> {{ one.Name, two.Age } });//可自定義返回類型
foreach (var v in onesSelectMany4)
{
Console.WriteLine(v); //v=匿名類型
}
#endregion
Console.ReadLine();
打印輸出
支持
May Be —— 開發者,總有一天要做的事!
Chinar 提供一站式《零》基礎教程 使有限時間 具備無限可能! |
Chinar 免費服務器、建站教程全攻略!( Chinar Blog )
本博客爲非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均爲本人所擁有,本人保留所有法定權利。違者必究
對於需要複製、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯繫,留言,Email: [email protected]
對於經本博主明確授權和許可使用文章及內容的,使用時請註明文章或內容出處並註明網址