关于C#中的Select与SelectMany方法

Select

将序列中的每个元素投影到新表单。

实例1

IEnumerable<int> squares =
    Enumerable.Range(1, 10).Select(x => x * x);

foreach (int num in squares)
{
    Console.WriteLine(num);
}
/*
 This code produces the following output:

 1
 4
 9
 16
 25
 36
 49
 64
 81
 100
*/

实例2 

string[] fruits = { "apple", "banana", "mango", "orange",
                      "passionfruit", "grape" };

var query =
    fruits.Select((fruit, index) =>
                      new { index, str = fruit.Substring(0, index) });

foreach (var obj in query)
{
    Console.WriteLine("{0}", obj);
}

/*
 This code produces the following output:

 {index=0, str=}
 {index=1, str=b}
 {index=2, str=ma}
 {index=3, str=ora}
 {index=4, str=pass}
 {index=5, str=grape}
*/

SelectMany

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。

实例1:

class PetOwner
{
    public string Name { get; set; }
    public List<String> Pets { get; set; }
}

public static void SelectManyEx1()
{
    PetOwner[] petOwners =
        { new PetOwner { Name="Higa, Sidney",
              Pets = new List<string>{ "Scruffy", "Sam" } },
          new PetOwner { Name="Ashkenazi, Ronen",
              Pets = new List<string>{ "Walker", "Sugar" } },
          new PetOwner { Name="Price, Vernette",
              Pets = new List<string>{ "Scratches", "Diesel" } } };

    // Query using SelectMany().
    IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets);

    Console.WriteLine("Using SelectMany():");

    // Only one foreach loop is required to iterate
    // through the results since it is a
    // one-dimensional collection.
    foreach (string pet in query1)
    {
        Console.WriteLine(pet);
    }

    // This code shows how to use Select()
    // instead of SelectMany().
    IEnumerable<List<String>> query2 =
        petOwners.Select(petOwner => petOwner.Pets);

    Console.WriteLine("\nUsing Select():");

    // Notice that two foreach loops are required to
    // iterate through the results
    // because the query returns a collection of arrays.
    foreach (List<String> petList in query2)
    {
        foreach (string pet in petList)
        {
            Console.WriteLine(pet);
        }
        Console.WriteLine();
    }
}

/*
 This code produces the following output:

 Using SelectMany():
 Scruffy
 Sam
 Walker
 Sugar
 Scratches
 Diesel

 Using Select():
 Scruffy
 Sam

 Walker
 Sugar

 Scratches
 Diesel
*/

可以理解为,selectmany将二维平展为一维,构建了一个新的集合

实例2

class PetOwner
{
    public string Name { get; set; }
    public List<string> Pets { get; set; }
}

public static void SelectManyEx3()
{
    PetOwner[] petOwners =
        { new PetOwner { Name="Higa",
              Pets = new List<string>{ "Scruffy", "Sam" } },
          new PetOwner { Name="Ashkenazi",
              Pets = new List<string>{ "Walker", "Sugar" } },
          new PetOwner { Name="Price",
              Pets = new List<string>{ "Scratches", "Diesel" } },
          new PetOwner { Name="Hines",
              Pets = new List<string>{ "Dusty" } } };

    // Project the pet owner's name and the pet's name.
    var query =
        petOwners
        .SelectMany(petOwner => petOwner.Pets, (petOwner, petName) => new { petOwner, petName })
        .Where(ownerAndPet => ownerAndPet.petName.StartsWith("S"))
        .Select(ownerAndPet =>
                new
                {
                    Owner = ownerAndPet.petOwner.Name,
                    Pet = ownerAndPet.petName
                }
        );

    // Print the results.
    foreach (var obj in query)
    {
        Console.WriteLine(obj);
    }
}

// This code produces the following output:
//
// {Owner=Higa, Pet=Scruffy}
// {Owner=Higa, Pet=Sam}
// {Owner=Ashkenazi, Pet=Sugar}
// {Owner=Price, Pet=Scratches}

函数原型

public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TCollection,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection,TResult> resultSelector);

这里需要说明: 第一个委托执行的结果集会作为第二个委托的第二个参数传递

将上述代码简化如下:

 var query = petOwner.SelectMany(a => a.Pets, (a, b) => new { a, b});

这里的a就是petOwner集合本身,b就是a.Pets生成的新的集合。

所有上面的例子我们可以修改的更简单点,可以得到同样的结果

 var query =
     petOwners
     .SelectMany(petOwner => petOwner.Pets, (petOwner, petName) => new { petOwner.Name, petName })
     .Where(ownerAndPet => ownerAndPet.petName.StartsWith("S"))
     .Select(ownerAndPet => ownerAndPet); //这里的select也可以去掉

相关推荐

  1. 关于C#SelectSelectMany方法

    2024-01-25 23:36:01       62 阅读
  2. 关于goselect

    2024-01-25 23:36:01       45 阅读
  3. go函数方法区别go关于面向对象理解

    2024-01-25 23:36:01       47 阅读
  4. Go语言Select:深度解析实战案例

    2024-01-25 23:36:01       60 阅读
  5. 深入理解Go语言ChannelSelect

    2024-01-25 23:36:01       49 阅读
  6. C#方法

    2024-01-25 23:36:01       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-25 23:36:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-25 23:36:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-25 23:36:01       87 阅读
  4. Python语言-面向对象

    2024-01-25 23:36:01       96 阅读

热门阅读

  1. C# DLL嵌套调用时修改生效

    2024-01-25 23:36:01       53 阅读
  2. 地址解析协议

    2024-01-25 23:36:01       63 阅读
  3. MongoDB聚合:$currentOp

    2024-01-25 23:36:01       55 阅读
  4. C语言|判断和循环相关题目

    2024-01-25 23:36:01       61 阅读
  5. 一次Rust重写基础软件的实践(二)

    2024-01-25 23:36:01       48 阅读
  6. named_struct

    2024-01-25 23:36:01       63 阅读
  7. 五、C#与数据库交互(数据存储过程与触发器)

    2024-01-25 23:36:01       60 阅读
  8. android gradle 使用总结

    2024-01-25 23:36:01       60 阅读