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; }
var colours = red.Select((t, i) => new RGB(t, green[i], blue[i])).ToList();
Jeff Mercado provides an answer where three sequences are zipped. This can be generalized to any number of sequences with the limitation that all sequences then have to have the same item type.
Here is a generalized zip operator that handles varying input lengths and with suitable error handling and proper disposal of the enumerators:
static class EnumerableExtensions {
public static IEnumerable<TResult> Zip<TSource, TResult>(
this IEnumerable<IEnumerable<TSource>> source,
Func<IEnumerable<TSource>, TResult> resultSelector
) {
if (source == null)
throw new ArgumentNullException("source");
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
var enumerators = new List<IEnumerator<TSource>>();
try {
foreach (var enumerable in source) {
if (enumerable == null)
throw new ArgumentNullException();
enumerators.Add(enumerable.GetEnumerator());
}
while (enumerators.Aggregate(true, (moveNext, enumerator) => moveNext && enumerator.MoveNext()))
yield return resultSelector(enumerators.Select(enumerator => enumerator.Current));
}
finally {
foreach (var enumerator in enumerators)
enumerator.Dispose();
}
}
}
The colors can then be computed using this generalized zip operator:
var reds = new[] { 0x00, 0x03, 0x06, 0x08, 0x09 };
var greens = new[] { 0x00, 0x05, 0x06, 0x07, 0x0a };
var blues = new[] { 0x00, 0x02, 0x03, 0x05, 0x09 };
var colors = new[] { reds, greens, blues }
.Zip(rgb => new RGB(rgb.First(), rgb.Skip(1).First(), rgb.Skip(2).First()));
The code may not be as elegant as some of the other solutions but a generalized zip operator might be useful in some situations and the code I have provided is efficient because it only iterates each source sequence once.