【问题标题】:Linq: group by year and month, and manage empty monthsLinq:按年和月分组,管理空月
【发布时间】:2010-11-22 13:30:00
【问题描述】:

我有以下 Linq 按年分组列表,然后按月。

var changesPerYearAndMonth = list
              .GroupBy(revision => new { revision.LocalTimeStamp.Year, revision.LocalTimeStamp.Month })
              .Select(group => new { GroupCriteria = group.Key, Count = group.Count() })
              .OrderBy(x => x.GroupCriteria.Year)
              .ThenBy(x => x.GroupCriteria.Month);

我目前的输出如下:

Year 2005, month 1, count 469
Year 2005, month 5, count 487
Year 2005, month 9, count 452
Year 2006, month 1, count 412
Year 2006, month 5, count 470
...

如您所见,没有价值的月份不包括在查询中。我想包括它们,具有以下输出:

Year 2005, month 1,  count 469
Year 2005, month 2,  count 0
Year 2005, month 3,  count 0
...
Year 2005, month 12, count 0
Year 2006, month 1,  count 412
Year 2006, month 2,  count 0
...
Year 2006, month 12, count 0

换句话说,我也需要得到空月。

我可以用 Linq 查询来实现吗?提前致谢

【问题讨论】:

  • 当我们可以在一个循环中更简单、更易读的时候,为什么还要花这么多时间来设计一个困难、不可读和低效的 Linq?
  • @Aliostad:到目前为止,Daniel 的 Linq 解决方案非常简单易读。如果这个问题的答案使用 Linq 太复杂,他总是可以退回到使用循环。
  • 好吧,我只是认为我们处于一个不正常的 Linq-mad 世界。你失去了所有的调试能力。关键是,类似于 XSLT,如果它变得太复杂,它就是纸牌屋。
  • 像这样使用OrderBy 两次是个坏主意。你应该使用OrderBy(x => x.GroupCriteria.Year).ThenBy(x => x.GroupCriteria.Month)。这是一个附带问题(这就是为什么我没有将其作为答案发布的原因)但它仍然值得了解。
  • @Aliostad:我不使用 linq,因为它是一个很好的练习……这就是原因,在我们的实验室中进行了测试。四百万个对象:用户使用 LINQ 获取修订计数:0 毫秒。通过用户迭代方法获取修订计数:780ms

标签: c# linq c#-4.0


【解决方案1】:

我想你想要这样的东西:

var changesPerYearAndMonth =
    from year in Enumerable.Range(2005, 6)
    from month in Enumerable.Range(1, 12)
    let key = new { Year = year, Month = month }
    join revision in list on key
              equals new { revision.LocalTimeStamp.Year, 
                           revision.LocalTimeStamp.Month } into g
    select new { GroupCriteria = key, Count = g.Count() };

注意:

  • 您需要知道您尝试为几年提供数据。当然,您可以从另一个查询中获取它,以找到所涉及的最小和最大年份 - 或者可能找到最小值并假设将来不会有任何事情(我不知道这是否是一个有效的假设)
  • 这将自动正确订购

【讨论】:

  • 乔恩斯基恩 1:我 0。但我不喜欢“你需要知道几年”的部分。您需要再进行一次查询才能知道您工作的年份。
  • 仍然失败... ") into g" 附近有错误(去掉括号)并且 g 没有 .Key 属性
  • @Daniel:好的,现在试试。忘记了GroupJoin的细节:)
  • @John,只有第 5 行的更正,它将是“在键列表中加入修订”。非常感谢!
  • @JonSkeet 如何修剪结果?例如,如果第一年的前 3 个月的 Count = 0 和/或去年的最后一个月的 Count = 0,我可能不想知道这些需求,因为它们很可能是“不符合顺序的” .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 2021-10-16
相关资源
最近更新 更多