助力快速理解 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: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址