助力快速理解 SelectMany 的高級用法 爲初學者節省寶貴的時間,避免採坑! |
我們的初衷是將一種簡單的生活方式帶給世人 使有限時間 具備無限可能 |
Chinar 教程效果:
1 Intro —— 簡介
SelectMany對於初學者來講,是一個比較難理解的函數。其內部邏輯,有點繞。
在使用上,對初學者來講,尤其是容易懵逼…
但它的用途極其廣泛,且極大的節省代碼、提高代碼可讀性。
避免大量的循環代碼
這裏我以 4個例子,說明SelectMany的多種用法。
請大家仔細、耐心的看完。
1.1 Constructor ―― 構造函數
Wait —— 敬請期待
設置tag —— 格子=Grid;物品=Good;
/// <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}";
}
}
初始化,填入數據
爲了便於大家理解,我用了
one、two、three 做爲3層嵌套的子父類;
one 對應的數據值爲: A、B、C、D
List<One> ones = new List<One> //第一層列表
{
new One("A1", 40, new List<Two> //第二層
{
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>
{
new Two("B2", 30, new List<Three> {new Three(14, 70)})
}),
new One("C1", 70, new List<Two>
{
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>
{
new Two("D2", 60, new List<Three> {new Three(40, 50)})
}),
};
2 Overload 1 —— 重載 1
我們來看下官方的代碼註釋:
//
// 摘要:
// 一個序列的每個元素投影 System.Collections.Generic.IEnumerable`1, ,並將合併爲一個序列將結果序列。 每個源元素的索引用於該元素的投影表。
//
// 參數:
// source:
// 一個要投影的值序列。
//
// selector:
// 一個應用於每個源元素的轉換函數;函數的第二個參數表示源元素的索引。
//
// 類型參數:
// TSource:
// 中的元素的類型 source。
//
// TResult:
// 返回的序列的元素的類型 selector。
//
// 返回結果:
// System.Collections.Generic.IEnumerable`1 其元素是一種一對多轉換函數對輸入序列中的每個元素調用的結果。
//
// 異常:
// T:System.ArgumentNullException:
// source 或 selector 爲 null。
public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector);
懵逼不?這纔是重載第一個
不要怕,有我,跟我來看個栗子
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
}
輸出結果
可以看出明顯區別。
SelectMany 作用:
Ones列表中的 每個元素 One 的實例,
每個 One 實例下都對應了幾個 TwoList 列表
將每個 TwoList 列表中的的元素 Two ,重新組合成一個包含了所有 TwoList的大列表;
還不理解?沒事,我給你們準備了張圖。
支持
May Be —— 開發者,總有一天要做的事!
Chinar 提供一站式《零》基礎教程 使有限時間 具備無限可能! |
Chinar 免費服務器、建站教程全攻略!( Chinar Blog )
本博客爲非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均爲本人所擁有,本人保留所有法定權利。違者必究
對於需要複製、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯繫,留言,Email: [email protected]
對於經本博主明確授權和許可使用文章及內容的,使用時請註明文章或內容出處並註明網址