SelectMany Linq

时间:2016-10-15 01:14:12

标签: c# linq

任何人都可以解释这个SelectMany语法

List<string> animals = new List<string>() { "cat", "dog", "donkey" };
List<int> number = new List<int>() { 10, 20 };
var mix=number.SelectMany(num => animals, (n, a) => new { n, a });

我不熟悉这种语法,因为我习惯于将它用于展平(以展平列表中的列表)

 public class x
 {
     public List<z> Zs{get; set;}
     public int Y { get; set; }
 }
 public class z
 {
     public int Y { get; set; }
 }
    List<x> Xs = new List<x>();
    Xs.Add(new x() { Zs = new List<z>() { new z() { Y = 15 } } });
    Xs.Add(new x() { Zs = new List<z>() { new z() { Y = 17 } } });
    Xs.Add(new x() { Zs = new List<z>() { new z() { Y = 19 } } });
    Xs.Add(new x() { Zs = new List<z>() { new z() { Y = 25 } } });
    Xs.Add(new x() { Zs = new List<z>() { new z() { Y = 50 } } });

Xs.SelectMany(x => x.Zs).Sum(z => z.Y);

1 个答案:

答案 0 :(得分:4)

检查来自Microsoft here

的参考来源

以下是正在使用的SelectMany重载

        public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector) 
        {
            if (source == null) throw Error.ArgumentNull("source");
            if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return SelectManyIterator<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
        }

        static IEnumerable<TResult> SelectManyIterator<TSource, TCollection, TResult>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector) 
        {
            foreach (TSource element in source) 
            {
                foreach (TCollection subElement in collectionSelector(element)) 
                {
                    yield return resultSelector(element, subElement);
                }
            }
        }

工作原理(这也是数据展平的形式)

  1. 类似于同心for / foreach循环,遍历两个集合并创建组合列表,其复杂度为O(N ^ 2)
  2. 首先,我们提供号码列表IEnumerable<TSource>
  3. 添加一个Func,每个number我们提供animal列表
  4. 最后只是将结果作为组合的匿名集合,每个数字都添加一个动物,结果就像

      n    a
    
      10   cat 
      10   dog 
      10   donkey 
      20   cat 
      20   dog 
      20   donkey