Merge multiple Lists into one List with LINQ

c#, design-patterns, linq

Solution

You're essentially trying to zip up three collections. If only the LINQ `Zip()` method supported zipping up more than two simultaneously. But alas, it only supports only two at a time. But we can make it work:

var reds = new List<int> { 0x00, 0x03, 0x06, 0x08, 0x09 };
var greens = new List<int> { 0x00, 0x05, 0x06, 0x07, 0x0a };
var blues = new List<int> { 0x00, 0x02, 0x03, 0x05, 0x09 };

var colors =
    reds.Zip(greens.Zip(blues), (red, tuple) =>
        new RGB(red, tuple.First, tuple.Second)
    )
    .ToList();

Of course it's not terribly painful to write up an extension method to do three (or more).

public static IEnumerable<TResult> Zip<TFirst, TSecond, TThird, TResult>(
    this IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    IEnumerable<TThird> third,
    Func<TFirst, TSecond, TThird, TResult> resultSelector)
{
    using (var enum1 = first.GetEnumerator())
    using (var enum2 = second.GetEnumerator())
    using (var enum3 = third.GetEnumerator())
    {
        while (enum1.MoveNext() && enum2.MoveNext() && enum3.MoveNext())
        {
            yield return resultSelector(
                enum1.Current,
                enum2.Current,
                enum3.Current
            );
        }
    }
}

This makes things a lot more nicer:

var colors =
    reds.Zip(greens, blues, (red, green, blue) =>
        new RGB(red, green, blue)
    )
    .ToList();

Problem

Is there a slick way to merge multiple Lists into a single List using LINQ to effectively replicate this? ``` public class RGB { public int Red { get; set; } public int Green { get; set; } public int Blue { get; set; } public RGB(int red, int green, int blue) { Red = red; Green = green; Blue = blue; } } public void myFunction() { List<int> red = new List<int> { 0x00, 0x03, 0x06, 0x08, 0x09 }; List<int> green = new List<int> { 0x00, 0x05, 0x06, 0x07, 0x0a }; List<int> blue = new List<int> { 0x00, 0x02, 0x03, 0x05, 0x09 }; List<RGB> colors = new List<RGB>(); colors.Add(new RGB(red[0], green[0], blue[0])); colors.Add(new RGB(red[1], green[1], blue[1])); colors.Add(new RGB(red[2], green[2], blue[2])); colors.Add(new RGB(red[3], green[3], blue[3])); colors.Add(new RGB(red[4], green[4], blue[4])); } ``` Or, since the lists arrive separately, its more effective to merge them sequentially like the following. ``` public class RGB { public int Red { get; set; } public int Green { get; set; } public int Blue { get; set; } public RGB(int red, int green, int blue) { Red = red; Green = green; Blue = blue; } } public void myFunction() { List<int> red = new List<int> { 0x00, 0x03, 0x06, 0x08, 0x09 }; List<RGB> colors = new List<RGB>(); colors.Add(new RGB(red[0], 0, 0)); colors.Add(new RGB(red[1], 0, 0)); colors.Add(new RGB(red[2], 0, 0)); colors.Add(new RGB(red[3], 0, 0)); colors.Add(new RGB(red[4], 0, 0)); List<int> green = new List<int> { 0x00, 0x05, 0x06, 0x07, 0x0a }; colors[0].Green = green[0]; colors[1].Green = green[1]; colors[2].Green = green[2]; colors[3].Green = green[3]; colors[4].Green = green[4]; List<int> blue = new List<int> { 0x00, 0x02, 0x03, 0x05, 0x09 }; colors[0].Blue = blue[0]; colors[1].Blue = blue[1]; colors[2].Blue = blue[2]; colors[3].Blue = blue[3]; colors[4].Blue = blue[4]; } ```

Original source

Related problems