介绍
SelectMany
方法在C#中用于将集合中的元素转换为其他类型的集合,并将这些集合扁平化为一个单一的序列。它是LINQ的一部分,允许你在一个序列上进行投影和过滤操作,然后将结果合并成一个序列。
方法定义
public static IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector
)
使用示例
准备测试类和初始代码
/// <summary>
/// 设备
/// </summary>
public class Device
{
public int Id { get; set; }
public string Name { get; set; }
public List<Point> Points { get; set; }
public Device()
{
Points = new List<Point>();
}
}
/// <summary>
/// 状态点位
/// </summary>
public class Point
{
public string PointId { get; set; }
public string Name { get; set; }
public int Value { get; set; }
}
//数据初始化
List<Device> list = new List<Device>();
list.Add(new Device() { Id = 101, Name = "1号设备", });
list.Add(new Device() { Id = 102, Name = "2号设备", });
list.Add(new Device() { Id = 103, Name = "3号设备", });
list.Add(new Device() { Id = 104, Name = "4号设备", });
list[0].Points.Add(new Point { PointId = "101-1", Name = "测试1", Value = 50 });
list[0].Points.Add(new Point { PointId = "101-2", Name = "测试2", Value = 50 });
list[1].Points.Add(new Point { PointId = "102-3", Name = "测试3", Value = 50 });
list[1].Points.Add(new Point { PointId = "102-4", Name = "测试4", Value = 50 });
list[1].Points.Add(new Point { PointId = "102-1", Name = "测试1", Value = 20 });
list[2].Points.Add(new Point { PointId = "103-2", Name = "测试2", Value = 3 });
list[3].Points.Add(new Point { PointId = "104-3", Name = "测试3", Value = 40 });
list[3].Points.Add(new Point { PointId = "104-4", Name = "测试4", Value = 40 });
使用:
var points = list.SelectMany(x => x.Points);
返回一个Point 的集合,他将原集合中每个对象的一个子集合,合并成了一个集合
在这个例子中,SelectMany
对每个 Device
对象调用 Points
属性,产生一个 Point
对象的序列。然后,SelectMany
将这些序列合并成一个单一的序列 allPoints
,其中包含了所有的 Point
对象。这样,你就可以遍历 allPoints
并访问每个 Point
对象的属性,而不需要关心它们属于哪个 Device
。
Select与SelectMany对比
对上述集合使用Select和SelectMany
var points1 = list.Select(x => x.Points);
var points2 = list.SelectMany(x => x.Points);
查看如下:可以看到Select是返回一个集合的集合,相当于是二维的集合,原有集合保持不变。
而SelectMany则是将各个子集合内容都添加到了同一个集合,这方便我们处理一些集合对象中 带有子集合的情况,可以直接获取到里面的所有对象,然后进行处理,省去了二次处理的麻烦。
结果对比:
特殊情况
在SelectMany
中必须返回集合对象IEnumerable<T>
,普通类型或者类都无法使用,使用则会报错。
但是有一种特殊情况,string类型可以被使用,这种情况下他被视为字符串数组char[]
,所以返回的结果也是IEnumerable<char>
,这种情况要注意,一般不会使用SelectMany
,要获取属性的集合,就使用Select