zoukankan      html  css  js  c++  java
  • 2.Linq实用性技巧篇

    在论坛上经常会看到别人问,linq怎么实现递归,如何求笛卡尔积等问题。。都可以用linq快速方便的解决。。下面我就来个总的归纳

    1.)递归

    我们经常会遇到一个情况,就是想获取当前节点下的所有子节点。比如我们查询的时候,条件选的广东,那么广州、深圳、东莞都在该范围内,当然还包括广州下的街道等。我们首先想到的是递归来解决。但如何结合linq呢?下面来看看吧

    复制代码
         static List<City> list = new List<City>()
            {
                new City{id=1,name="广东",parentid=0},
                new City{id=2,name="广州",parentid=1},
                new City{id=3,name="深圳",parentid=1},
                new City{id=4,name="东莞",parentid=1},
                new City{id=5,name="越秀区",parentid=2},
                new City{id=6,name="白云区",parentid=2},
            };
    
            static void Main(string[] args)
            {
                var result = GetChilds(list.First());
            }
    
            public static IEnumerable<City> GetChilds(City city)
            {
                var temp = list.Where(x => x.parentid == city.id);
                return temp.Concat(temp.SelectMany(x => GetChilds(x)));
            }
    复制代码

    很简单吧?这里我们可以就concat前后分2部份来看,temp为当前city的子节点temp.selectmany那里是找出该子节点下的子节点,这样就好理解了吧

    2.)笛卡尔积

    想到笛卡尔积,首先想到selectmany来处理

    复制代码
         static void Main(string[] args)
            {
                string[] s1 = { "A", "B", "C" };
                string[] s2 = { "D", "E" };
                var result = s1.SelectMany(x => s2.Select(y => x + y));
                foreach (var item in result)
                {
                    Console.WriteLine(item);
                }
                Console.ReadKey();
            }
    复制代码

    结果如我们所想。但是如果是3个或4个或更多的数组呢?或许你想到循环,递归等。但这里我要给大家介绍一样东西,叫累加器-Aggregate。

    复制代码
    static void Main(string[] args)
            {
                List<string[]> list = new List<string[]>();
                string[] s1 = { "A", "B", "C" };
                string[] s2 = { "D", "E" };
                string[] s3 = { "F", "G" };
                list.Add(s1);
                list.Add(s2);
                list.Add(s3);
    
                var result = list.Aggregate((thisCurrent, nextCurrent) => thisCurrent.SelectMany(x => nextCurrent.Select(y => x + y)).ToArray());
                foreach (var item in result)
                {
                    Console.WriteLine(item);
                }
                Console.ReadKey();
            }
    复制代码

    运行结果

    其实就是尾递归。

    (thisCurrent, nextCurrent) => thisCurrent.SelectMany(x => nextCurrent.Select(y => x + y)).ToArray()
    thisCurrent.SelectMany(x => nextCurrent.Select(y => x + y)).ToArray()会作为参数传到下次的thisCurrent中

    3.)分组查询小介绍

    linq的分组非常强大,用起来也非常爽。比如有一群人,我们想按他们的年龄进行分组,每10岁分一组,我们会这么做

    复制代码
     static void Main(string[] args)
            {
                List<int> list = new List<int>()
                {
                    6,7,8,9,12,15,18,23,25,33,31,39,40
                };
                var result = list.GroupBy(x => x / 10);
                foreach (var item in result)
                {
                    Console.WriteLine(string.Join(",", item));
                }
                Console.ReadLine();
            }
    复制代码

    这里我就不截图了。很简单粗暴。

    但如果我们想将1~18岁的归位一组(儿童组),18~28(青年组),29~40为(成人组)那我们该怎么办呢?还要加上个性别,分成女青年组 男青年组等,40岁以上的不分男女,统一归位老人组。这时大家怎么办呢?LINQ照样简单粗暴的解决问题

    复制代码
      public class Person
        {
            public string name { get; set; }
            public int age { get; set; }
            public string sex { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                List<Person> list = new List<Person>()
                {
                    new Person(){name="小A",age=5,sex="男"},
                    new Person(){name="小B",age=5,sex="女"},
                    new Person(){name="小C",age=7,sex="男"},
                    new Person(){name="小D",age=12,sex="男"},
                    new Person(){name="小E",age=20,sex="女"},
                    new Person(){name="小F",age=21,sex="男"},
                    new Person(){name="小G",age=25,sex="男"},
                    new Person(){name="小H",age=39,sex="男"},
                    new Person(){name="小I",age=55,sex="男"},
                    new Person(){name="小J",age=54,sex="女"},
                };
                var result = list.GroupBy(x =>
                {
                    if (x.age <= 18)
                        return x.sex + "儿童组";
                    if (x.age > 18 && x.age <= 28)
                        return x.sex + "青年组";
                    if (x.age > 28 && x.age <= 40)
                        return x.sex + "成人组";
                    return "老人组";
                });
    
                foreach (var item in result)
                {
                    string name = string.Join(",", item.Select(x => x.name));
                    Console.WriteLine(string.Format("{0}:{1}", item.Key, name));
                }
                Console.ReadKey();
            }
    复制代码

    运行结果

    不知道大家学到东西没。。LINQ很灵活,关键就看你怎么玩了。。用得好的话一句话就能解决很多复杂的东西

     
  • 相关阅读:
    Kotlin入门(20)几种常见的对话框
    Kotlin入门(19)Android的基础布局
    Kotlin入门(18)利用单例对象获取时间
    Kotlin入门(17)等式判断的情况
    Kotlin入门(16)容器的遍历方式
    Kotlin入门(15)独门秘笈之特殊类
    Android Studio Gradle被墙bug总结
    unity常用的坐标系转换
    欧拉角与万向节死锁
    Unity导出Gradle工程给Android Studio使用
  • 原文地址:https://www.cnblogs.com/zhangxiaolei521/p/5552162.html
Copyright © 2011-2022 走看看