zoukankan      html  css  js  c++  java
  • LINQ to Object——延时执行的Enumerable类方法

    LINQ to Object是针对实现了IEnumerable<T>的对象的LINQ。而在System.Linq.Enumerable类中,总共定义了40来个查询运算符----全部用扩展方法来实现,他们被称为标准查询运算符。每个查询运算符的执行行为不同,大致分为立即执行和延时执行。延时执行,顾名思义就是不是立即执行,即不是在查询语句定义的时候执行,而是在处理结果集(如遍历)的时候执行。

    常用的延时执行的Enumerable类方法成员,具体如下:

    1.Take用于从一个序列的开头返回指定数量的元素

                string[] names = { "张三", "范冰冰", "李冰冰", "迈克尔·杰克逊", "李四", "王五", "赵六", "田七" };
    
                //在数组上直接使用Take方法
                foreach (string name in names.Take(3))       //获取前三个元素
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
    
                //在LINQ返回的IEnumerable<T>序列上使用Take方法
                var take_names = from string name in names
                            where name.Length >= 3       //获取名字长度大于等于3的元素
                            select name;
                foreach (string name in take_names.Take(3))       //获取前三个元素
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    2.TakeWhile 用于获取指定序列从头开始符合条件的元素,直到遇到不符合条件的元素为止

                var takewhile_names = names.TakeWhile(n => n.Length < 4);       //获取从头开始名称长度小于4的元素,遇到不符合条件的就结束
                foreach (string name in takewhile_names)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
    
                var takewhile_names2 = names.TakeWhile((n, i) => n.Length < 4 && i < 2);       //获取从头开始名称长度小于4的元素,遇到不符合条件的就结束,并取当前元素索引小于2的元素,即前两个
                foreach (string name in takewhile_names2)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    3.Skip跳过序列中指定数量的元素

                foreach (string name in names.Skip(5))       //跳过前5个元素
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
    
                var skip_names = (from name in names
                                  where name.Length >= 3       //获得名字长度大于等于3的元素
                                  select name).Skip(1);       //跳过前1个元素
                foreach (string name in skip_names.Skip(1))       //再跳过前个元素
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    4.SkipWhile 用于跳过序列中满足条件的元素,然会返回剩下的元素

                var skipwhile_names = names.SkipWhile(n => n.Length < 3);       //跳过名字长度小于3的
                foreach (string name in skipwhile_names)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                var skipwhile_names2 = names.SkipWhile((n, i) => n.Length <= 3 && i >= 0);       //跳过名字长度小于3的,并且取当前索引大于等于的元素,即第一个往后的
                foreach (string name in skipwhile_names2)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    Take和Skip的简单综合应用:获取第M到N个的元素

                var skipandtake_names = names.Skip(5).Take(3);       //获取第6到8的元素
                foreach (string name in skipandtake_names)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");

    5.Reverse用于翻转序列中的元素的顺序

                string str = "反转字符串";
                var restr = str.ToCharArray().Reverse();
                foreach (var newstr in restr)
                {
                    Console.WriteLine(newstr);
                }
                Console.WriteLine("----------------------------");
    var re_names = names.Reverse();
                foreach (var new_names in re_names)
                {
                    Console.WriteLine(new_names);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    6.Distinct过滤掉重复的元素

                string[] names2 = { "张三", "范冰冰", "李冰冰", "迈克尔·杰克逊", "李四", "王五", "赵六", "田七", "张三", “大帅哥” };
                var distinct_names = names2.Distinct();
    
                foreach (var new_names in distinct_names)
                {
                    Console.WriteLine(new_names);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    7.Union用于合并两个序列,并去掉重复项

                var union_names = names.Union(names2);
                foreach (string name in union_names)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    8.Concat用于连接两个序列,不会去掉重复项

                var concat_names = names.Concat(names2);
                foreach (string name in concat_names)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    9.Intersect用于获得两个序列的交集

                var intersect_names = names.Intersect(names2);
                foreach (string name in intersect_names)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    10.Except用于获得两个序列的差集(注意:两个序列是谁减谁)

                var except_names = names2.Except(names);
                foreach (string name in except_names)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    11.Range 用于生成指定范围内的“整数”序列

                var number = Enumerable.Range(10, 5);
                number.ToList().ForEach(n => Console.WriteLine("{0}", n));
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    12.Repeat用于生成指定数量的重复元素

                var person = new { Name = "张三", Age = 20 };
                var persons = Enumerable.Repeat(person, 5);
                persons.ToList().ForEach(n => Console.WriteLine("{0} 年龄:{1}", n.Name, n.Age));
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    13.Empty 用于获得一个指定类型的空序列

                var empty = Enumerable.Empty<string>();

    14.DefaultIfEmpty 用于获得序列,如果为空,则添加一个默认类型元素

    直接给一个int类型空集合:

                var intempty = Enumerable.Empty<int>();
                Console.WriteLine(intempty.Count());
                Console.WriteLine("----------------------------");
                foreach (var n in intempty)
                {
                    Console.WriteLine(n);
                }
                Console.WriteLine("----------------------------");
                Console.WriteLine(intempty.DefaultIfEmpty().Count());       //默认为0
                Console.WriteLine("----------------------------");
                foreach (var n in intempty.DefaultIfEmpty())
                {
                    Console.WriteLine(n);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    或者获得一个空对象集合:

                var new_personList = from name in names
                            where name == "123"
                            select name;
                Console.WriteLine(new_personList.Count());
                Console.WriteLine(new_personList.DefaultIfEmpty().Count());       //默认为null
                foreach (var n in new_personList.DefaultIfEmpty())
                {
                    Console.WriteLine(n);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();

    运行结果:

    或者指定一个默认值:

                foreach (var n in intempty.DefaultIfEmpty(100))
                {
                    Console.WriteLine(n);
                }
                Console.WriteLine("----------------------------");
                Console.ReadKey();
    
                foreach (var n in new_personList.DefaultIfEmpty("张三"))
                {
                    Console.WriteLine(n);
                }
                Console.ReadKey();

    运行结果:

    15.OfType筛选指定类型的元素

                ArrayList names3 = new ArrayList();
                names3.Add("李四");
                names3.Add("王五");
                names3.Add(100);
                names3.Add(new Person { Name = "张三", Age = 20, Phone = "333333" });
                var oftype_names = names3.OfType<string>();
                oftype_names.ToList().ForEach(n => Console.WriteLine(n));
                Console.ReadKey();

    运行结果:

    16.Cast类型转换

                var cast_names = names3.OfType<string>().Cast<string>();

    17.AsEnumerable有些数据源类型不支持Enumerable的部分查询关键字,需要转换下,譬如IQueryable

                var asEnumerable_names = cast_names.AsEnumerable();

    常用延时执行的Enumerable类方法整理完毕!

  • 相关阅读:
    转:同步、异步、阻塞和非阻塞
    转:回调函数
    转:同步/异步与阻塞/非阻塞的区别
    转:Socket在阻塞模式下的信息收发和文件接收
    转:直接用socket实现HTTP协议
    链接错误 LINK : fatal error LNK1104: 无法打开文件“XX.obj”
    转:MFC中常用类,宏,函数介绍
    转:线程同步技术剖析
    转:线程同步
    转:C++回调函数用法
  • 原文地址:https://www.cnblogs.com/jiechou/p/9218420.html
Copyright © 2011-2022 走看看