C#LinQSelectMany中文詳解-Chinar-Linq語法大全

Chinar blog www.chinar.xin

SelectMany中文詳解


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

助力快速理解 SelectMany 具體用途,4重載分析

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

Chinar —— 心分享、心創新!

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

使有限時間 具備無限可能

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 )


Chinar

END

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

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

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

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