C# Linq中的Select和SelectMany

这篇具有很好参考价值的文章主要介绍了C# Linq中的Select和SelectMany。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C#中Linq的select 语句很好理解,因为这个select类似于sql语句中的select——筛选出感兴趣的字段,但是SelectMany就不好理解了,本文主要讲解一下SelectMany,顺便和Select对比。

 

目录

1.SelectMany的官方定义

 2.例子

3. Select和SelectMany的对比

4.SelectMany的扩展



1.SelectMany的官方定义

        官方定义很简单,就是一句话:将一个序列中的每个元素映射成一个可枚举对象,然后将这些对象合并到一个序列中。C# Linq中的Select和SelectMany

 看完可能还是有点懵逼,我们再看看函数定义:

C# Linq中的Select和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);

注意第一个参数:

Func<TSource,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector

传入的是一个func,func的入参为原集合的元素,对应起来就是PetOwner,返回的是Pets成员,也就是集合,从名字上来说就是指定要flatten的集合,简而言之就是给我把Owner的Pets全部撸到一个集合里面去。

第二个参数:

Func<TSource,TCollection,TResult> resultSelector

就是一个选择器,从TSource和TCollection中选择,构成TResult。

如果只是想获取所有的pets信息;可以用另一个版本:

public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,System.Collections.Generic.IEnumerable<TResult>> selector);
 // 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);
    }

3. Select和SelectMany的对比

看下面的例子:

public class PhoneNumber
{
    public string Number { get; set; }
}

public class Person
{
    public IEnumerable<PhoneNumber> PhoneNumbers { get; set; }
    public string Name { get; set; }
}

IEnumerable<Person> people = new List<Person>();

// Select gets a list of lists of phone numbers
IEnumerable<IEnumerable<PhoneNumber>> phoneLists = people.Select(p => p.PhoneNumbers);

// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);

这个例子简单明了:用Select得到的是List<List<>>结构,而SelectMany得到的是List<>,所以官方定义会中有flatten这个词。

所以前面的例子用Select代替就可以写为:

 // 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();
    }

4.SelectMany的扩展

        官方还提供了一个能获取索引的版本:

public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,System.Collections.Generic.IEnumerable<TResult>> selector);

也就是比上一个版本对一个Int类型参数! 

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

public static void SelectManyEx2()
{
    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" } },
          new PetOwner { Name="Hines, Patrick",
              Pets = new List<string>{ "Dusty" } } };

    // Project the items in the array by appending the index
    // of each PetOwner to each pet's name in that petOwner's
    // array of pets.
    IEnumerable<string> query =
        petOwners.SelectMany((petOwner, index) =>
                                 petOwner.Pets.Select(pet => index + pet));

    foreach (string pet in query)
    {
        Console.WriteLine(pet);
    }
}

// This code produces the following output:
//
// 0Scruffy
// 0Sam
// 1Walker
// 1Sugar
// 2Scratches
// 2Diesel
// 3Dusty

注意,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 });

foreach(var x in mix)
{
    Console.WriteLine(x.n+"=="+x.a);
}

这样可以很方便的生成笛卡尔积形式结果:文章来源地址https://www.toymoban.com/news/detail-456500.html

10==cat
10==dog
10==donkey
20==cat
20==dog
20==donkey

到了这里,关于C# Linq中的Select和SelectMany的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL之优化SELECT语句

    本文主题为MySQL优化SELECT语句,涵盖了数据库性能提升概述,WHERE子句优化,范围优化和哈希联接优化。在数据库性能方面,需要考虑软件结构、CPU和I/O操作的最小化和高效执行。WHERE子句优化涉及改进查询的算法和可读性。范围优化介绍了优化器使用范围访问方法的条件和方

    2024年02月14日
    浏览(48)
  • MySQL Select 语句执行顺序

    一条 SQL 查询语句结构如下: 但真正的执行步骤如下,执行时,每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入: 1. FROM 在这一步,无论后面跟那种联接运算(LEFT JOIN、RIGHT JOIN等),都首先执行交叉联接(CROSS JOIN),计算笛卡尔积,生成虚拟表 VT-1 2. ON 根

    2024年02月05日
    浏览(41)
  • MySQL(3):基本的 SELECT 语句

    SQL(Structured Query Language,结构化查询语言)是使用关系模型的数据库应用语言, 与数据直接打交道 。 SQL 有两个重要的标准,分别是 SQL92 和 SQL99,它们分别代表了 92 年和 99 年颁布的 SQL 标准,我们今天使用的 SQL 语言依然遵循这些标准。 不同的数据库生产厂商都支持SQL语句

    2024年02月08日
    浏览(34)
  • MySQL(六):基本的SELECT语句

    本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远! 语法: 选择全部列: 一般情况下,除非需要使用表中所有的字段数据,最好不要使用通配符‘ *

    2024年02月08日
    浏览(38)
  • DQL语句(一) -----简单select查询

    select 列名*N from 表名 where 查询条件1 and/or 查询条件2 group by 列 Having 分组条件 Order by 排序 sql在书写时 除了查询条件 外,大小写都可以 select * from user where uname=\\\'zs\\\'; SELECT *FROM USER WHERE UNAME=\\\'zs\\\'; 要是在公司要 看其他员工 sql是大写还是小写 -- 属于sql语句的注释 所有查询条件为字

    2024年02月05日
    浏览(36)
  • [SQL挖掘机] - SELECT语句

    当我们处理数据库时, 经常需要从表中获取特定的数据. 为了实现这个目的, 我们使用一种称为\\\"select\\\"的语句. 简单来说, select语句就像一个过滤器或者选择器, 帮助我们选择 (select) 想要的数据. 通过编写select语句并执行查询操作, 我们可以按照我们的需求从数据库中提取特定的数

    2024年02月15日
    浏览(51)
  • 【MySQL系列】- SELECT语句执行顺序

    2.1 执行FROM操作 这一步需要做的是对FROM子句前后的两张表进行笛卡尔积操作,也称作为交叉连接,生成虚拟表VT1。如果FROM子句前的表包含a行数据,FROM子句后的表中包含b行数据,那么虚拟表VT1将包含a*b行数据。 2.2 应用ON过滤器 SELECT查询共有3个过滤流程,分别是ON、WHERE、

    2024年02月08日
    浏览(47)
  • SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解

    SELECT INTO 语句将数据从一个表复制到一个新表中。 新表将按照在旧表中定义的列名和类型创建。您可以使用 AS 子句创建新的列名。 以下 SQL 语句创建 Customers 的备份副本: 以下 SQL 语句使用 IN 子句将表复制到另一个数据库中的新表中: 以下 SQL 语句仅复制一些列到新表中:

    2024年02月05日
    浏览(117)
  • MYSQL-SELECT语句超详解

    目录 前言: SELECT语法 示例 单个字段查询 多个字段查询 查询所有字段 没有FROM的SELECT  查询系统时间 数值计算 虚拟表dual WHERE语句  示例 = AND OR 比较运算符 AND  OR  运算符优先级  IN  NOT IN  BETWEEN NOT BETWEEN LIKE EXISTS ORDER BY  LIMIT DISTINCT 前言: 示例中操作的表为 Sakila 示例数

    2024年02月12日
    浏览(67)
  • MySQL基础(三)基本的SELECT语句

    1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖。在这几十年里,无数的技术、产业在这片江湖里沉浮,有的方兴未艾,有的已经几幕兴衰。但在这片浩荡的波动里,有一门技术从未消失,甚至“老当益壮”,那就是 SQL。

    2024年02月03日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包