【问题标题】:Linq Query to Group by and Sum into new list [duplicate]Linq查询分组并汇总到新列表中[重复]
【发布时间】:2015-05-01 09:24:27
【问题描述】:

所以我在尝试构建查询时做了一个小小的噩梦,尽管它真的不应该那么困难。

我有一个类visitItem

public class visitItem
{
    public int visitId {get; set;}
    public int contactId {get; set;}
    public int locationId {get; set;}
    public DateTime FirstSeen {get; set;}
    public DateTime LastSeen {get; set;}
    public double Duration {get; set;}
}

基本上我在 json 中访问历史日期,我将其反序列化为 visitItem 列表,并从数据中形成几个不同的图表。

我想要做的是从我选择特定月份的主列表中创建一个新列表,结果列表现在按 contactId 分组,并且持续时间相加:

List<visitItem> totalDurations = visits
  .Where(x => x.FirstSeen.ToString("MM") == month)......

这样就选择了相关月份的数据,然后我希望列表如下:

contactId          duration
1                  10
2                  5
3                  5
4                  20

代替:

contactId          duration
1                  5
1                  5 
2                  5
3                  5
4                  10
4                  10

我怎样才能做到这一点?

【问题讨论】:

  • 你为什么要执行字符串转换?当然使用FirstSeen.Month 会更简单......无论如何,你还没有解释为什么你想要第一个输出,或者输入是什么......目前你刚刚说过你想要它是 X 而不是 Y,这给了我们很少的上下文来帮助你......
  • 啊 - 重新格式化问题后,它更有意义。请注意在发布问题之前预览问题,以确保它确实有意义。
  • 接下来,您您已按contactId 分组,但您根本没有显示查询的那部分,这再次让人难以提供帮助。理想情况下,提供一个简短但完整的程序来演示问题...
  • 抱歉,原帖中的格式不正确。我现在才回头看,我认为我的答案与上面的编辑后完全一样。我并不是说我是按contactId 分组的,我的意思是我首先只选择第x 个月的访问来获得相关列表。然后应该对结果列表进行分组和汇总等。感谢您的帮助

标签: c# linq


【解决方案1】:

您需要按月份过滤,然后按联系人 ID 对项目进行分组,然后对这些组的持续时间求和。例如,对于 5 月:

var month = 5;

var durationByContact = from visit in visits
                        where visit.FirstSeen.Month == month
                        group visit by visit.contactId
                        into visitsByContact
                        select new
                        {
                            ContactId = visitsByContact.Key,
                            TotalDuration = visitsByContact.Sum(i => i.Duration)
                        };

或者在方法语法中:

var durationByContact = visits
    .Where(v => v.FirstSeen.Month == month)
    .GroupBy(v => v.contactId)
    .Select(g => new
    {
        ContactId = g.Key,
        TotalDuration = g.Sum(i => i.Duration)
    });

【讨论】:

  • 不,它是按月过滤,按联系人ID分组
  • @JonSkeet 你是对的 - 问题编辑解释得更好我不确定之前是否清楚。我已经更新了。
  • 感谢您的回复。这正是我想要的。我只是将其编辑为Select(g =&gt; new visitItem{ContactId = g.Key, Duration = g.Sum(i =&gt; i.Duration}),以便在 foreach 循环中轻松使用并避免匿名类型的列表。
  • 作为附加查询,如何在查询的选择部分包含 FirstSeen?例如.Select(g =&gt; new visitItem{ContactId = g.Key, TotalDuration = g.Sum(i =&gt; i.Duration), FirstSeen = ???});
  • 你想要FirstSeen 的值是多少?由于您仅按contactId 进行分组,因此FirstSeen 在该组中可能有不同的值(尽管所有值都在month 中,正如您首先过滤的那样)。
猜你喜欢
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 2018-11-24
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多