Linq语法关键字总结+示例代码(全)-Chinar

Chinar blog www.chinar.xin

Linq 函数大全教程


本文提供全流程,中文翻译

助力查询学习 LinQ 查询语句的具体用法、可用于备忘

为初学者节省宝贵的时间,避免采坑!

Chinar —— 心分享、心创新!

我们的初衷是将一种简单的生活方式带给世人

使有限时间 具备无限可能

Chinar 教程效果:



全文高清图片,点击即可放大观看 (很多人竟然不知道)


1. Where —— 筛选/过滤


Where —— 筛选满足条件的数据

举个例子

找 重量大于 30的狗

List<Dog> dogs = new List<Dog>()
{
    new Dog("金毛",  2000, 62),
    new Dog("二哈",  1500, 45),
    new Dog("泰迪",  1000, 15),
    new Dog("吉娃娃", 500,  10)
};

//1-查询 狗狗中 重量大于30
dogs.Where(dog => dog.Weight > 30).ToList().ForEach(dog => print(dog.ToString()));

打印输出:

Name: 金毛, Price: 2000, Weight: 62
Name: 二哈, Price: 1500, Weight: 45

Name: 金毛, Price: 2000, Weight: 62
Name: 二哈, Price: 1500, Weight: 45

数据类 —— 为了简化代码,将该类放于 ChinarDemo.LinQ 命名空间中。便于以下例子使用此数据!

namespace ChinarDemo.LinQ
{
    /// <summary>
    /// 狗狗数据类
    /// </summary>
    public class Dog
    {
        public string Name;   //名称
        public int    Price;  //价格
        public float  Weight; //重量


        /// <summary>
        /// 构造 —— 简化代码
        /// </summary>
        public Dog(string name, int price, float weight)
        {
            Name   = name;
            Price  = price;
            Weight = weight;
        }


        /// <summary>
        /// 便于打印输出看效果 —— 简化代码
        /// </summary>
        public override string ToString()
        {
            return $"{nameof(Name)}: {Name}, {nameof(Price)}: {Price}, {nameof(Weight)}: {Weight}";
        }
    }
}

2. Select —— 返回选定类型


Select —— 从数据中返回指定的数据类型

举个例子

1:从dogs序列中,返回狗的名字新序列
2:从dogs序列中,返回狗的价格新序列
3:从dogs序列中,返回狗的重量新序列

List<Dog> dogs = new List<Dog>()
{
    new Dog("金毛",  2000, 62),
    new Dog("二哈",  1500, 45),
    new Dog("泰迪",  1000, 15),
    new Dog("吉娃娃", 500,  10)
};


dogs.Select(_=>_.Name).ToList().ForEach(_=>Console.WriteLine(_));//( 狗的名字 )返回新的序列
dogs.Select(_=>_.Price).ToList().ForEach(_=>Console.WriteLine(_));//( 狗的价格 )返回新的序列
dogs.Select(_ => _.Weight).ToList().ForEach(_ => Console.WriteLine(_));//( 狗的重量 )返回新的序列

打印输出:

金毛
二哈
泰迪
吉娃娃

2000
1500
1000
500

62
45
15
10

2.1 SelectMany —— 返回多个选定类型/协程排序


SelectMany —— 一个序列中每个元素的投影,合并为一个序列,并返回。
在 UniRx 中多用于对协程执行顺序进行管理

举个例子

将狗狗的名字拆分为字符类型,并返回
对3个协程依照需求顺序执行

/// <summary>
/// 第一层
/// </summary>
public class One
{
    public string    Name;    //名字
    public int       Age;     //年龄
    public List<Two> TwoList; //儿子


    public One(string name, int age, List<Two> twoList)
    {
        Name    = name;
        Age     = age;
        TwoList = twoList;
    }
}


/// <summary>
/// 第二层
/// </summary>
public class Two
{
    public string      Name;      //名字
    public int         Age;       //年龄
    public List<Three> ThreeList; //儿子


    public Two(string name, int age, List<Three> threeList)
    {
        Name      = name;
        Age       = age;
        ThreeList = threeList;
    }


    public override string ToString()
    {
        return $"{nameof(Name)}: {Name}, {nameof(Age)}: {Age}, {nameof(ThreeList)}: {ThreeList}";
    }
}


/// <summary>
/// 第三层
/// </summary>
public class Three
{
    public int Age;   //年龄
    public int Score; //分数


    public Three(int age, int score)
    {
        Age   = age;
        Score = score;
    }


    public override string ToString()
    {
        return $"{nameof(Age)}: {Age}, {nameof(Score)}: {Score}";
    }
}


class Program
{
    static void Main(string[] args)
    {
        List<One> ones = new List<One> //第一层列表
        {
            new One("A1", 40, new List<Two> //第二层
            {
                new Two("A2_0", 20, new List<Three> {new Three(10, 100)}), //第三层
                new Two("A2_1", 20, new List<Three> {new Three(10, 100)}), //第三层
                new Two("A2_2", 20, new List<Three> {new Three(10, 100)})  //第三层
            }),
            new One("B1", 50, new List<Two>
            {
                new Two("B2", 30, new List<Three> {new Three(14, 70)})
            }),
            new One("C1", 70, new List<Two>
            {
                new Two("C2_0", 50, new List<Three> {new Three(25, 80)}),
                new Two("C2_1", 50, new List<Three> {new Three(25, 80)})
            }),
            new One("D1", 80, new List<Two>
            {
                new Two("D2", 60, new List<Three> {new Three(40, 50)})
            }),
        };
        #region 重载1

        IEnumerable<List<Two>> onesSelect     = ones.Select(_ => _.TwoList);     //Select 返回 List<Two>
        IEnumerable<Two>       onesSelectMany = ones.SelectMany(_ => _.TwoList); //第一个重载:返回 Two
        foreach (var v in onesSelect)
        {
            Console.WriteLine(v); //v=List<Two>
        }

        Console.WriteLine("----------------------------");
        foreach (var v in onesSelectMany)
        {
            Console.WriteLine(v); //v=Two
        }

        #endregion
        #region 重载 二

        Console.WriteLine("----------重载 二 ------------");
        //var onesSelectMany2 = ones.SelectMany((a, b) =>
        //    a.TwoList.Select(_ =>
        //    {
        //        _.Name = b + "---" + _.Name;
        //        return _;
        //    }));

        //这里的 index 指的是 List<One> ones 中对象的索引
        IEnumerable<string> onesSelectMany2 = ones.SelectMany((one, index) => one.TwoList.Select(_ => "索引:" + index + "--名字:" + _.Name));
        foreach (var v in onesSelectMany2)
        {
            Console.WriteLine(v); //v=String
        }

        #endregion
        Console.ReadLine();
    }

打印输出:

在这里插入图片描述


3. First —— 首次/第一个数据


First —— 返回数据中的第一项数据

举个例子

取数组中满足条件的 第一项 元素

int[] numbers  = {1, 2, 3, 4, 5, 6};        //数组
var   numFirst = numbers.First(i => i > 3); //返回满足条件的第一个数据元素
print(numFirst);                            //输出 4

打印输出:

4

4. Distinct —— 找不同


Distinct —— 不同的元素通过,相同元素被剔除

举个例子

//一个数据列表,并添加数据
List<int> ints = new List<int>()
{
    1, 2, 2, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
ints.Distinct().ToList().ForEach(_ => print(_)); //遍历输出,剔除后的列表

打印输出:相同元素被剔除,返回不同的

12345678910

5. Last —— 找不同


Last —— 最后一个元素

举个例子

找到狗狗中的最后一个/满足条件的最后一个

List<Dog> dogs = new List<Dog>()
{
    new Dog("金毛",  2000, 62),
    new Dog("二哈",  1500, 45),
    new Dog("泰迪",  1000, 15),
    new Dog("吉娃娃", 500,  10)
};

Dog dog = dogs.Last();                     //最后一个
print(dog.ToString());                     //:吉娃娃
Dog dog1 = dogs.Last(_ => _.Price > 1000); //传入条件:价格在 1000以上 的狗中的最后一个。这里由于数组是2000先加入,1500后加入。所以1500在后,返回的是1500。而并非2000
print(dog1.ToString());                    //:二哈

打印输出:

Name: 吉娃娃, Price: 500, Weight: 10

Name: 二哈, Price: 1500, Weight: 45

6. Union —— 并集


  • Union —— 取2个集合的并集
  • 其实就是 2个序列中,剔除所有重复元素,取唯一值合并为一个序列

举个例子

剔除所有重复元素,取唯一,合并序列

int[]  chinarArray1 = new int[] {1, 2, 3, 4, 5};
int[]  chinarArray2 = new int[] {1, 4, 8, 6, 3, 2};
var    unionList    = chinarArray1.Union(chinarArray2).ToList();
string resultStr    = "";
unionList.ForEach(_ => resultStr = resultStr + _.ToString());
print(resultStr);

打印输出:

1234586

7. (Min/Max/Count/Sum) —— 最小/最大/数量/求和


  • Min ——序列中 最小值
  • Max ——序列中 最大值
  • Count ——序列元素的 数量
  • Sum ——序列中元素 求和

举个例子

数组中元素求和,取最大/最小值/元素数量

int[] ints  = new[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
var   min   = ints.Min();
var   max   = ints.Max();
var   count = ints.Count();
var   sum   = ints.Sum();
Console.WriteLine(min);   //0
Console.WriteLine(max);   //9
Console.WriteLine(count); //10
Console.WriteLine(sum);   //45

打印输出:

0
9
10
45

8. OrderBy/Descending —— 升序/降序


  • OrderBy —— 按照给定条件对序列元素升序排序
  • OrderByDescending —— 按照给定条件对序列元素降序排序

举个例子

将一个散乱的数组,升序,降序 排列

int[] ints       = {5, 2, 8, 6, 4, 0, 3, 7, 9, 1};          //数字排序很乱的数组
var   ascending  = ints.OrderBy(_ => _).ToList();           //升序
var   descending = ints.OrderByDescending(_ => _).ToList(); //降序
ascending.ForEach(Console.Write);                           //0123456789
Console.WriteLine();                                        //换行
descending.ForEach(Console.Write);                          //9876543210
Console.ReadKey();

打印输出:

0123456789
9876543210

9. Skip/Take —— 跳过、取定范围


基础都是依照 序列顺序 依次执行

  • Skip —— 跳过指定数量元素,取剩余元素
  • SkipWhile —— 根据(条件)跳过指定数量元素,取剩余元素
  • Take —— 只取指定数量元素,跳过剩余元素
  • TakeWhile —— 根据(条件)只取指定数量元素,跳过剩余元素

takeWhile0 坑点:

  • 这里第一项就小于5,条件不满足返回 false
  • 后边的元素就不再进行比较了,比较结束
  • 所以没有取到任何元素,跳过了剩余所有元素。
  • Count 为 0

SkipWhileTakeWhile
二者都是在条件为 false 时,结束比较

举个例子

skip 跳过前10项,取剩余元素
skipWhile 跳过小于 5 元素,取剩余元素
take 只取前10项,跳过剩余元素
takeWhile 只取小于 5 元素,跳过剩余元素

int[] ints      = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
var   skip      = ints.Skip(10).ToList();              //跳过前 10 项元素,取剩余元素
var   skipWhile = ints.SkipWhile(_ => _ < 5).ToList(); //跳过小于 5 元素,取剩余元素
var   take      = ints.Take(10).ToList();              //只取前 10 项元素,跳过剩余元素
var   takeWhile = ints.TakeWhile(_ => _ < 5).ToList(); //只取小于 5 元素,跳过剩余元素
skip.ForEach(_ => Console.Write(_ + "-"));             //10-11-12-13-14-15-16-17-18-19-
Console.WriteLine();                                   //
skipWhile.ForEach(_ => Console.Write(_ + "-"));        //5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-
Console.WriteLine();                                   //
take.ForEach(_ => Console.Write(_ + "-"));             //0-1-2-3-4-5-6-7-8-9-
Console.WriteLine();                                   //
takeWhile.ForEach(_ => Console.Write(_ + "-"));        //0-1-2-3-4-
Console.WriteLine();                                   //

var takeWhile0 = ints.TakeWhile(_ => _ > 5).ToList();//跳过了所有元素,取不到任何元素
Console.WriteLine("takeWhile0 数量为:" + takeWhile0.Count);// 0
Console.ReadKey();

打印输出:

10-11-12-13-14-15-16-17-18-19-
5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-
0-1-2-3-4-5-6-7-8-9-
0-1-2-3-4-
takeWhile0 数量为:0

10. OfType —— 类型筛选


  • OfType —— 根据指定类型,筛选对象

举个例子

从一个 Object[]数组中,找出指定类型元素

  • 找出类型为 Int 的元素
  • 找出类型为 String 的元素
object[] objects    = {1, 2, 3, 4, 5, "字符1", "字符2", "字符3"};
var      intList    = objects.OfType<int>().ToList();    //找出类型为 Int 的元素
var      stringList = objects.OfType<string>().ToList(); //找出 String 元素
intList.ForEach(_ => Console.Write(_ + "-"));    //1-2-3-4-5-
Console.WriteLine();
stringList.ForEach(_ => Console.Write(_ + "-")); //字符1-字符2-字符3-
Console.ReadKey();

打印输出:

1-2-3-4-5-
字符1-字符2-字符3-

11. Intersect —— 交集


  • Intersect —— 取两个序列的交集,也就是两个序列的相同元素

举个例子

两个数组序列中,找出相同元素,生成两个序列的交集

  • 135
  • 张三、李四
int[]            ints1         = {1, 2, 3, 4, 5};
int[]            ints2         = {1, 3, 5, 7, 9};
IEnumerable<int> intersectInts = ints1.Intersect(ints2);
//135 为两个数组相同元素,被返回
intersectInts.ToList().ForEach(Console.Write);
Console.WriteLine();


string[]            strs1            = {"张三", "李四"};
string[]            strs2            = {"张三", "李四", "王五", "干啥呢?"};
IEnumerable<string> intersectIntStrs = strs1.Intersect(strs2);
//张三、李四 
intersectIntStrs.ToList().ForEach(Console.Write);
Console.ReadKey();

打印输出:

135
张三李四

12. Except —— 差集


  • Except —— 取两个序列的差集,求出A、B中彼此没有的元素

Except 坑点:

  • 序列A/B取差集,顺序不同,返回结果不同
  • 也就是A except B,与B except A是不同d

要点就是:
A序列取B序列 —— 返回A有,B没有的值
B序列取A序列 —— 返回B有,A没有的值

如此简单

举个例子

将2个整数序列,1和2数组分别求差集

  • 相互调换位置,看结果
int[] ints1    = {1, 2, 3, 4, 5}; //独有的为:2、4
int[] ints2    = {1, 3, 5, 7, 9}; //独有的为:7、9
var   except12 = ints1.Except(ints2);
except12.ToList().ForEach(Console.Write); //24
Console.WriteLine();
Console.WriteLine("以下为 2 取 1");
var except21 = ints2.Except(ints1);
except21.ToList().ForEach(Console.Write); //79
Console.ReadKey();

打印输出:

24
以下为 21
79

支持

May Be —— 开发者,总有一天要做的事!


拥有自己的服务器,无需再找攻略

Chinar 提供一站式《零》基础教程

使有限时间 具备无限可能!

Chinar 知你所想,予你所求!( Chinar Blog )


Chinar

END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值