You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用LINQ按时间范围分组统计符合指定代码集的对象?

高效实现基于时间和人员的事件分组统计需求

需求说明

  • 先按PersonKey(人员标识)对TestData对象列表进行分组;
  • 每个分组内,筛选出ActionCode匹配指定代码集的条目(代码顺序无要求);
  • 仅当该代码集对应的所有条目都处于60分钟的时间范围内时,才进行统计;
  • 已被分组统计的事件(EventKey)不再参与后续统计。

现有实现逻辑粗糙、效率低下,需要更高效的解决方案。

代码示例

public class TestData
{
    public int PersonKey { set; get; }
    public int EventKey { set; get; }
    public string ActionCode { set; get; }
    public DateTime ActionDate { set; get; }
}

public static void DoSummary()
{
    // 示例统计规则
    var section1 = new { name = "Section 1", codes = new List<string>(new string[] { "code1", "code2" }) };
    var section2 = new { name = "Section 2", codes = new List<string>(new string[] { "code1", "code3", "code4" }) };
    var section3 = new { name = "Section 3", codes = new List<string>(new string[] { "code1", "code2", "code5" }) };
    var list = new List<TestData>();
    
    // 过滤出包含指定代码的条目
    list = list.Where(x => section2.codes.Contains(x.ActionCode)).ToList();
    
    for (int year = 2010; year < 2023; year++)
    {
        // 存储已统计过的事件ID,避免重复统计
        var skipEvents = new List<int>();
        // 筛选当前年份的数据
        var yearData = list.Where(x => x.ActionDate.Year == year);
        // 按人员标识分组
        var people_in_year = yearData.GroupBy(x => x.PersonKey);
        int count = 0;
        
        // 仅处理事件数大于1的人员分组
        foreach (var g in people_in_year.Where(x => x.Count() > 1))
        {
            foreach (var ev in g)
            {
                var testList = new List<int>();
                bool allCodesFound = true;
                
                foreach (var otherCode in section1.codes.Where(x => x != ev.ActionCode))
                {
                    var found = g.Where(x => !skipEvents.Contains(x.EventKey) && x.ActionCode == otherCode &&
                        // 确保两个事件的时间差在60分钟内
                        (ev.ActionDate - x.ActionDate).TotalMinutes > -60 &&
                        (ev.ActionDate - x.ActionDate).TotalMinutes < 60
                    ).ToList();
                    
                    if (found.Count > 0)
                    {
                        // 收集匹配到的事件ID,后续标记为已统计
                        testList.AddRange(found.Select(x => x.EventKey));
                    }
                    else
                    {
                        allCodesFound = false;
                    }
                }
                
                if (allCodesFound)
                {
                    // 将匹配到的事件加入跳过列表,避免重复统计
                    skipEvents.AddRange(testList);
                    count++;
                }
            }
        }
    }
}

补充说明

一旦事件被分组统计,其EventKey将被标记,不再参与任何后续统计。

内容的提问来源于stack exchange,提问作者Andy Le

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:22:47