【问题标题】:Split one list into many by month - C#, Linq按月将一个列表拆分为多个 - C#、Linq
【发布时间】:2012-05-16 22:26:31
【问题描述】:

我有以下 Linq 查询:

List<MonthlySales> monthlySales = (from sale in Sales
                     group sale by new { sale.DateSold.Month, sale.Product.Shop } into ds
                     select new MonthlyTitleSales
                     {
                         Shop = ds.Select(it => it.Product.Shop).FirstOrDefault(),
                         Month = ds.Select(it => it.DateSold.Month).FirstOrDefault(),
                         Year = ds.Select(it => it.DateSold.Year).FirstOrDefault(),
                         USDNumberItemsSold = ds.Where(it => it.USDCut.HasValue).Where(it => it.USDCut != 0).Count(),
                         GBPNumberItemsSold = ds.Where(it => it.GBPCut.HasValue).Where(it => it.GBPCut != 0).Count(),
                         EURNumberItemsSold = ds.Where(it => it.EURCut.HasValue).Where(it => it.EURCut != 0).Count(),
                         USDRevenueTotal = PerformCurrencyConversion(ds.Sum(it => it.USDCut.HasValue ? it.USDCut.Value : 0), 0M, 0M, Currency, endDate),
                         GBPRevenueTotal = PerformCurrencyConversion(0M, ds.Sum(it => it.GBPCut.HasValue ? it.GBPCut.Value : 0), 0M, Currency, endDate),
                         EURRevenueTotal = PerformCurrencyConversion(0M, 0M, ds.Sum(it => it.EURCut.HasValue ? it.EURCut.Value : 0), Currency, endDate),
                     }).OrderBy(it => it.DateSold.Month).ToList();

此查询为我提供了一个列表,其中每个列表项中包含以下元素: 店铺、月份、年份、收入

我最终需要做的是计算所有商店每个月的收入中位数,因此我需要以允许我这样做的方式准备好数据。

我认为一种方法可能是按月将此列表分成小列表,但我怀疑这是最有效的解决方案。

有人对此有什么想法吗?

为任何需要看的人提供每月销售课程:

public class MonthlySales
    {
        public int Month { get; set; }
        public int Year { get; set; }

        public Shop Shop { get; set; }

        public int USDNumberItemsSold { get; set; }
        public int GBPNumberItemsSold { get; set; }
        public int EURNumberItemsSold { get; set; }
        public int TotalNumberItemsSold { get { return USDNumberItemsSold + GBPNumberItemsSold + EURNumberItemsSold; } }

        public decimal USDRevenueTotal { get; set; }
        public decimal GBPRevenueTotal { get; set; }
        public decimal EURRevenueTotal { get; set; }
        public decimal OverallEarnings { get { return USDRevenueTotal + GBPRevenueTotal + EURRevenueTotal; } }
    }

【问题讨论】:

    标签: c# linq list median


    【解决方案1】:

    您可以使用GroupBy 将列表按月分组。例如,以下将按月(实际上是月+年)分组,然后将每个月的所有值写入控制台:

    var grouped = monthlySales.GroupBy(ms => string.Format("{0}-{1}", ms.Month, ms.Year));
    
    foreach(var group in grouped)
    {
         Console.WriteLine("Values in month-year of {0}:", group.Key);
         foreach(var ms in group)
             Console.WriteLine("   {0}", ms.USDRevenueTotal);
    }
    

    【讨论】:

      【解决方案2】:

      GroupBy 非常适合这个问题。还可以考虑 ToLookup(您可以使用相同的代码,只需将 GroupBy 更改为 ToLookup)。

      区别:

      • GroupBy 是懒惰的。
      • ToLookup 是急切的。

      • GroupBy,由于它的懒惰性质,依赖于源头来产生结果。如果源发生更改,则 GroupBy 结果将包含更改 - 它已连接。
      • ToLookup,由于其急切的性质,不关心源是否更改或消失 - 它已断开连接。

      • GroupBy 返回一个IEnumerable&lt;IGrouping&lt;TKey, TValue&gt;&gt;,只适合循环遍历。
      • ToLookup 返回一个ILookup&lt;TKey, TValue&gt;,它与Dictionary&lt;TKey, List&lt;TValue&gt;&gt; 相似,因为它支持按键查找,此外也是一个IEnumerable&lt;IGrouping&lt;TKey, TValue&gt;&gt;

      另外 - 考虑替代键的字符串。这是一个用作键的匿名类:

      var grouped = monthlySales.GroupBy(ms => new {ms.Month, ms.Year}); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-05
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 2018-11-25
        • 1970-01-01
        • 2019-03-14
        • 2019-06-05
        相关资源
        最近更新 更多