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

如何计算员工指定门禁区域停留时长?(避免嵌套循环判断)

员工指定门禁区域停留时长计算

数据背景

现有存储于eventList中的GateEvent对象列表,每个对象包含以下属性:

  • Employee:员工信息(每位员工对应唯一门禁权限)
  • GateTitle:门禁名称
  • Timestamp:事件时间戳
  • InsidePremises:是否在目标区域内
  • EntryGranted:门禁通行是否被允许(仅通过指定门禁时为true)

权限与状态规则

  • 员工仅能通过指定门禁(如示例中John Doe仅可通过Assembly line门禁),尝试非指定门禁时EntryGranted返回false
  • 通过指定门禁且InsidePremises从true变为false时,表示员工离开区域;首次进入指定门禁时无前置状态,直接标记为true
  • 非指定门禁的通行尝试不改变员工的InsidePremises状态

示例代码与输出

遍历事件列表代码

foreach(GateEvent x in eventList)
{
   Console.WriteLine($"{x.Employee} | {x.GateTitle} | {x.Timestamp} | {x.EntryGranted} | {x.InsidePremises}");
}

遍历输出示例

...
John Doe | Assembly line | 2022-10-06 08:51:27 | true | true // 进入区域
John Doe | Sales office | 2022-10-06 09:41:07 | false | true // 无法通行,仍在Assembly line区域
John Doe | Assembly line| 2022-10-06 10:00:08 | true | false // 离开区域
John Doe | Sales office | 2022-10-06 10:10:05 | false | false // 无法通行,不在工作区域
John Doe | Assembly line | 2022-10-06 11:53:00 | true | true // 再次进入区域
John Doe | Management | 2022-10-06 12:00:00 | false | true // 无法通行,仍在Assembly line区域
John Doe | Assembly line | 2022-10-06 14:03:40 | true | false // 离开区域
...

需求目标

计算员工在Assembly line区域的单次停留时长(即每个InsidePremises=true到false的时间区间时长),要求避免在for循环中使用嵌套if语句实现。

实现方案(C#)

利用LINQ链式调用,通过分组、筛选、配对事件的方式实现,全程无嵌套if:

// 按员工分组,筛选指定门禁的有效通行记录并计算停留时长
var employeeStayDetails = eventList
    // 只保留Assembly line门禁的有效通行事件
    .Where(e => e.GateTitle == "Assembly line" && e.EntryGranted)
    // 按员工分组
    .GroupBy(e => e.Employee)
    .Select(group => new
    {
        EmployeeName = group.Key,
        // 对当前员工的事件按时间排序,配对进入/离开事件计算时长
        StayRecords = group.OrderBy(e => e.Timestamp)
            .Select((evt, idx) => new { Event = evt, Index = idx })
            // 仅取偶数索引的进入事件(对应下一个奇数索引的离开事件)
            .Where(pair => pair.Index % 2 == 0 && pair.Index + 1 < group.Count())
            .Select(pair =>
            {
                var enterEvent = pair.Event;
                var leaveEvent = group.OrderBy(e => e.Timestamp).ElementAt(pair.Index + 1);
                return new
                {
                    EnterTime = enterEvent.Timestamp,
                    LeaveTime = leaveEvent.Timestamp,
                    Duration = leaveEvent.Timestamp - enterEvent.Timestamp
                };
            })
    });

// 输出计算结果
foreach(var employeeData in employeeStayDetails)
{
    Console.WriteLine($"员工: {employeeData.EmployeeName}");
    foreach(var record in employeeData.StayRecords)
    {
        Console.WriteLine($"进入时间: {record.EnterTime}, 离开时间: {record.LeaveTime}, 停留时长: {record.Duration}");
    }
}

方案说明

  1. 先过滤掉非指定门禁、通行失败的无效事件,只保留有效通行记录
  2. 按员工分组后,对每个员工的事件按时间排序
  3. 通过索引奇偶性自动配对进入(偶数位)和离开(奇数位)事件,直接计算时间差
  4. 全程使用LINQ链式调用替代传统循环嵌套,避免了冗余的条件判断

内容的提问来源于stack exchange,提问作者Justas Xibu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:50:16