Merge multiple Lists into one List with LINQ

前端 未结 8 1762
南方客
南方客 2020-11-28 12:50

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; }         


        
相关标签:
8条回答
  • 2020-11-28 13:36
    var colours = red.Select((t, i) => new RGB(t, green[i], blue[i])).ToList();
    
    0 讨论(0)
  • 2020-11-28 13:38

    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.

    0 讨论(0)
提交回复
热议问题