Linq下有一个非常实用的SelectMany方法,很多人却不会用

Posted kennard_owen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linq下有一个非常实用的SelectMany方法,很多人却不会用相关的知识,希望对你有一定的参考价值。

在平时开发中经常会看到有些朋友或者同事在写代码时会充斥着各种for,foreach,这种程式代码太多的话阅读性特别差,而且还显得特别累赘,其实在FCL中有很多帮助我们提高阅读感的方法,而现实中很多人不会用或者说不知道,这篇我就跟大家聊一聊。

一:SelectMany

这个方法绝对是提高开发速度的一大利器,有太多的业务场景需要使用这个函数,举一个我实际应用场景,商家按照年份和客户类型预先设置一些标签,然后让系统跑一下它的各自标签到底有多少人?

1. 定义Model

为了方便演示,这里做了一下简化代码,只有一个字典,key表示年份,value:就是该年份的多组标签。


    public class EstimateModel
    {
        public int ShopID { get; set; }
    <span class="hljs-comment">//key: 年份</span>
    <span class="hljs-keyword">public</span> Dictionary&lt;<span class="hljs-built_in">string</span>, List&lt;TagCrowdFilterModel&gt;&gt; YearCrowdFilterDict { get; <span class="hljs-built_in">set</span>; }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TagCrowdFilterModel</span>
{</span>
    <span class="hljs-comment">/// &lt;summary&gt;</span>
    <span class="hljs-comment">/// 筛选条件</span>
    <span class="hljs-comment">/// &lt;/summary&gt;</span>
    <span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> CrowdFiter { get; <span class="hljs-built_in">set</span>; }

    <span class="hljs-comment">/// &lt;summary&gt;</span>
    <span class="hljs-comment">/// 获取人数</span>
    <span class="hljs-comment">/// &lt;/summary&gt;</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> TotalCustomerCount { get; <span class="hljs-built_in">set</span>; }
}

为了更加清晰,我决定再填充一下数据

        public static void Main(string[] args)
        {
            var estimateModel = new EstimateModel()
            {
                ShopID = 1,
                YearCrowdFilterDict = new Dictionary<string, List<TagCrowdFilterModel>>()
                {
                    {
                        "17年",new List<TagCrowdFilterModel>()
                               {
                                 new TagCrowdFilterModel(){ CrowdFiter="between 10 and 20" },
                                 new TagCrowdFilterModel(){ CrowdFiter=" a<10  || a>30" },
                               }
                    },
                    {
                        "18年",new List<TagCrowdFilterModel>()
                               {
                                 new TagCrowdFilterModel(){ CrowdFiter="between 100 and 200" },
                                 new TagCrowdFilterModel(){ CrowdFiter=" a<100  || a>300" },
                               }
                    },
                    {
                        "19年",new List<TagCrowdFilterModel>()
                               {
                                 new TagCrowdFilterModel(){ CrowdFiter="between 1000 and 2000" },
                                 new TagCrowdFilterModel(){ CrowdFiter=" a<1000  || a>3000" },
                               }
                    }
                }
            };
        }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">GetCustomerID</span><span class="hljs-params">(<span class="hljs-built_in">string</span> crowdfilter)</span>
    </span>{
        <span class="hljs-keyword">return</span> BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), <span class="hljs-number">0</span>);
    }

2. 实现需求

需求也很简单,就是依次获取 TagCrowdFilterModel 中的 CrowdFiter 字段再调用GetCustomerID方法把人数赋值给TotalCustomerCount即可,这么简单的需求,如果让你来搞定,你该怎么实现这个逻辑? 没错,很多人可能就是两个foreach搞定。

        foreach (var year in estimateModel.YearCrowdFilterDict.Keys)
        {
            var yearCrowdFitlerList = estimateModel.YearCrowdFilterDict[year];
        foreach (var crowdFitler in yearCrowdFitlerList)
        {
            crowdFitler.TotalCustomerCount = GetCustomerID(crowdFitler.CrowdFiter);
        }
    }

看似代码也很清爽,但现实哪有这么好的事情,真实情况是年份上可能还要套上一个客户类型,客户类型之上再套一个商品,商品之上再套一个商家,这样很深的层级你就需要多达3个foreach,4个foreach甚至5个foreach才能搞定,再放张图给大家看看,是不是看着头大...

以上是关于Linq下有一个非常实用的SelectMany方法,很多人却不会用的主要内容,如果未能解决你的问题,请参考以下文章

温故知新C# Linq中 Select && SelectMany 使用技巧

LINQ操作符二:SelectMany

如何仅在 javascript 中执行相当于 LINQ SelectMany() 的操作

Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析

何时更喜欢用 SelectMany() 表示的连接而不是用 Linq 中的 join 关键字表示的连接

LINQ to SQL [npgsql] 从 SelectMany 生成不正确的查询