SelectMany() 究竟是做什么用的?
Exactly what SelectMany() is for?
没有输入和输出很难解释这个。我制作了一个简单的汽车示例,以避免我的项目中不必要的细节。
我有这个列表:
List<car> cars = new List<car>()
{
new car() { carname = "bmw", carwheels = new List<int>() { 1, 2, 3, 4 } },
new car() { carname = "cadillac", carwheels = new List<int>() { 1, 2, 3, 4 } },
new car() { carname = "mustang", carwheels = new List<int>() { 1, 2, 3, 4 } }
};
我想输出扩展名 类:
{
{ carname = "bmw", carwheel = 1 },
{ carname = "bmw", carwheel = 2 },
{ carname = "bmw", carwheel = 3 },
{ carname = "bmw", carwheel = 4 },
{ carname = "cadillac", carwheel = 1 },
{ carname = "cadillac", carwheel = 2 },
{ carname = "cadillac", carwheel = 3 },
{ carname = "cadillac", carwheel = 4 },
{ carname = "mustang", carwheel = 1 },
{ carname = "mustang", carwheel = 2 },
{ carname = "mustang", carwheel = 3 },
{ carname = "mustang", carwheel = 4 }
}
有没有办法通过 IEnumerable 扩展方法进行投影?与 SelectMany() 相反的东西。
它不是 SelectMany()
的 相反 ,而是 SelectMany()
的确切用途。你可以这样实现:
var result = cars.SelectMany(c =>
c.carwheels.Select(w => new
{
carname = c.carname,
carwheel = w
})).ToList();
内部 Select
将每辆汽车的车轮投射到一个新对象(在我的代码中是具有您指定属性的匿名类型)。外层 SelectMany()
将这些序列压平成一个列表。
也许这个解决方案会有帮助?这会将您的 IEnumerable 拆分为固定大小的 IEnumerable
public static class EnumerableExtension
{
private static IEnumerable<T> GetChunk<T>(IEnumerator<T> source, int size)
{
yield return source.Current;
for (int i = 1; i < size; i++)
{
if (source.MoveNext())
{
yield return source.Current;
}
else
{
yield break;
}
}
}
public static IEnumerable<IEnumerable<T>> SplitToChunks<T>(this IEnumerable<T> source, int size)
{
if (size < 1)
{
throw new ArgumentOutOfRangeException();
}
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return GetChunk(enumerator, size);
}
}
}
}
抱歉,没有正确阅读问题)
这是我发现冗长的 Linq 语法更具可读性的罕见情况之一:
var query = from car in cars
from carwheel in car.carwheels
select new { car.carname, carwheel };
没有输入和输出很难解释这个。我制作了一个简单的汽车示例,以避免我的项目中不必要的细节。
我有这个列表:
List<car> cars = new List<car>()
{
new car() { carname = "bmw", carwheels = new List<int>() { 1, 2, 3, 4 } },
new car() { carname = "cadillac", carwheels = new List<int>() { 1, 2, 3, 4 } },
new car() { carname = "mustang", carwheels = new List<int>() { 1, 2, 3, 4 } }
};
我想输出扩展名 类:
{
{ carname = "bmw", carwheel = 1 },
{ carname = "bmw", carwheel = 2 },
{ carname = "bmw", carwheel = 3 },
{ carname = "bmw", carwheel = 4 },
{ carname = "cadillac", carwheel = 1 },
{ carname = "cadillac", carwheel = 2 },
{ carname = "cadillac", carwheel = 3 },
{ carname = "cadillac", carwheel = 4 },
{ carname = "mustang", carwheel = 1 },
{ carname = "mustang", carwheel = 2 },
{ carname = "mustang", carwheel = 3 },
{ carname = "mustang", carwheel = 4 }
}
有没有办法通过 IEnumerable 扩展方法进行投影?与 SelectMany() 相反的东西。
它不是 SelectMany()
的 相反 ,而是 SelectMany()
的确切用途。你可以这样实现:
var result = cars.SelectMany(c =>
c.carwheels.Select(w => new
{
carname = c.carname,
carwheel = w
})).ToList();
内部 Select
将每辆汽车的车轮投射到一个新对象(在我的代码中是具有您指定属性的匿名类型)。外层 SelectMany()
将这些序列压平成一个列表。
也许这个解决方案会有帮助?这会将您的 IEnumerable 拆分为固定大小的 IEnumerable
public static class EnumerableExtension
{
private static IEnumerable<T> GetChunk<T>(IEnumerator<T> source, int size)
{
yield return source.Current;
for (int i = 1; i < size; i++)
{
if (source.MoveNext())
{
yield return source.Current;
}
else
{
yield break;
}
}
}
public static IEnumerable<IEnumerable<T>> SplitToChunks<T>(this IEnumerable<T> source, int size)
{
if (size < 1)
{
throw new ArgumentOutOfRangeException();
}
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return GetChunk(enumerator, size);
}
}
}
}
抱歉,没有正确阅读问题)
这是我发现冗长的 Linq 语法更具可读性的罕见情况之一:
var query = from car in cars
from carwheel in car.carwheels
select new { car.carname, carwheel };