Linq中SelectMany圖文詳解-Chinar

Chinar blog www.chinar.xin

SelectMany中文教程


本文提供全流程,中文翻譯

助力快速理解 SelectMany 的高級用法

爲初學者節省寶貴的時間,避免採坑!

Chinar —— 心分享、心創新!

我們的初衷是將一種簡單的生活方式帶給世人

使有限時間 具備無限可能

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 )


Chinar

END

本博客爲非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均爲本人所擁有,本人保留所有法定權利。違者必究

對於需要複製、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯繫,留言,Email: [email protected]

對於經本博主明確授權和許可使用文章及內容的,使用時請註明文章或內容出處並註明網址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章