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; }
For what it's worth, I like LINQ and use it frequently, but sometimes the old-fashioned way is the best. Note these examples:
const int Max = 100000;
var rnd = new Random();
var list1 = Enumerable.Range(1, Max).Select(r => rnd.Next(Max)).ToList();
var list2 = Enumerable.Range(1, Max).Select(r => rnd.Next(Max)).ToList();
DateTime start;
start = DateTime.Now;
var r1 = list1.Zip(list2, (a, b) => new { a, b }).ToList();
var time1 = DateTime.Now - start;
start = DateTime.Now;
var r2 = list1.Select((l1, i) => new { a = l1, b = list2[i]}).ToList();
var time2 = DateTime.Now - start;
start = DateTime.Now;
var r3 = new int[0].Select(i => new { a = 0, b = 0 }).ToList();
// Easy out-of-bounds prevention not offered in solution #2 (if list2 has fewer items)
int max = Math.Max(list1.Count, list2.Count);
for (int i = 0; i < max; i++)
r3.Add(new { a = list1[i], b = list2[i] });
var time3 = DateTime.Now - start;
Debug.WriteLine("r1 == r2: {0}", r1.SequenceEqual(r2));
Debug.WriteLine("r1 == r3: {0}", r1.SequenceEqual(r3));
Debug.WriteLine("time1 {0}", time1);
Debug.WriteLine("time2 {0}", time2);
Debug.WriteLine("time3 {0}", time3);
The output is:
r1 == r2: True
r1 == r3: True
time1 00:00:00.0100071
time2 00:00:00.0170138
time3 00:00:00.0040028
Of course, the time is barely noticeable in this case (to human perception) so it comes down to preference, but knowing #3 is by far the fastest, I'd tend to use it in critical performance areas where the types were more complex or the enumerables could be large.
Also, note the difference when using 3:
const int Max = 100000;
var rnd = new Random();
var list1 = Enumerable.Range(1, Max).Select(r => rnd.Next(Max)).ToList();
var list2 = Enumerable.Range(1, Max).Select(r => rnd.Next(Max)).ToList();
var list3 = Enumerable.Range(1, Max).Select(r => rnd.Next(Max)).ToList();
DateTime start;
start = DateTime.Now;
var r1 = list1.Zip(list2, (a, b) => new { a, b }).Zip(list3, (ab, c) => new { ab.a, ab.b, c }).ToList();
var time1 = DateTime.Now - start;
start = DateTime.Now;
var r2 = list1.Select((l1, i) => new { a = l1, b = list2[i], c = list3[i] }).ToList();
var time2 = DateTime.Now - start;
start = DateTime.Now;
var r3 = new int[0].Select(i => new { a = 0, b = 0, c = 0 }).ToList();
// Easy out-of-bounds prevention not offered in solution #2 (if list2 or list3 have fewer items)
int max = new int[] { list1.Count, list2.Count, list3.Count }.Max();
for (int i = 0; i < max; i++)
r3.Add(new { a = list1[i], b = list2[i], c = list3[i] });
var time3 = DateTime.Now - start;
Debug.WriteLine("r1 == r2: {0}", r1.SequenceEqual(r2));
Debug.WriteLine("r1 == r3: {0}", r1.SequenceEqual(r3));
Debug.WriteLine("time1 {0}", time1);
Debug.WriteLine("time2 {0}", time2);
Debug.WriteLine("time3 {0}", time3);
The output:
r1 == r2: True
r1 == r3: True
time1 00:00:00.0280393
time2 00:00:00.0089870
time3 00:00:00.0050041
As expected, the .zip method has to do multiple iterations and becomes the slowest.