SelectMany()究竟是为了什么?

时间:2016-08-22 15:23:32

标签: c# enumerable

如果没有输入和输出,很难解释这一点。我做了一个简单的Car示例,以避免不必要的项目细节。

我有这个清单:

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()相反的东西。

3 个答案:

答案 0 :(得分:6)

它不是SelectMany()相反,而是SelectMany()的确切含义。你可以这样做:

var result = cars.SelectMany(c => 
            c.carwheels.Select(w => new 
            {
                carname = c.carname,
                carwheel = w
            })).ToList();

内部Select将每辆车的轮子投影到一个新对象(在我的具有指定属性的匿名类型的代码中)。外部SelectMany()将这些序列展平为一个列表。

答案 1 :(得分:4)

这是我发现详细的Linq语法更具可读性的极少数情况之一:

 var query = from car in cars
             from carwheel in car.carwheels
             select new { car.carname, carwheel };

答案 2 :(得分:-2)

也许这个解决方案会有所帮助?这会将您的IEnumerable拆分为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);
            }
        }
    }

}

抱歉,没有正确阅读问题)