数据表和最小值 IF?

问题描述 投票:0回答:1

我有一个数据表,其中包含以下列,以及用于描述我正在使用的内容的示例数据。

确认号码 打卡上班 打卡下班
500012 08:00 16:00
500013 08:00 11:00
500014 10:00 12:00
500015 15:00 17:00

在此示例中,我将对确认号 500013 进行计算。

我使用此表来计算按比例的小时预订(即,如果两个时钟重叠,则它们重叠的时间应平均共享),我为此选择的方法本质上是计算每个时钟之间重叠的时钟数量相关时间事件。

我需要找到某种方法来返回“时钟输入”和“时钟输出”列中的最小值,其中这些值晚于“扫描时间”。流程应该是这样的:

  1. 确定在 08:00 开始时间,有两个打卡时间。
  2. 在此表中查找下一个值,即 500014 于 10:00 打卡上班。取 8 点到 10 点之间的两个小时,除以该持续时间内的确认数量 (2),然后将 1 小时传递给保持变量。
  3. 由于下一个值是打卡,重叠确认的数量现在为 3。
  4. 在表中查找下一个值,即 11:00 的下班时间 500013。将该小时除以 3,传递给持有变量,使按比例预订的总小时数为 1.3333333。

如果不逐一迭代整个列表,我无法想出执行步骤 2 的明智方法。 C# 中是否有像 Excel 中那样的内置 MINIF 函数,可以发送数字列表并返回最小的数字,但前提是约束认为它为真(在本例中是 newtime > oldtime)?

如果迭代列表中的每个项目是唯一的方法,那么这就是我必须做的,但如果可能的话,我更愿意将其整齐地打包。

c# if-statement datatable minimum
1个回答
0
投票

虽然 C# 没有像 Excel 的 MINIF 这样的内置函数,但您可以通过迭代列表并手动应用约束来实现所需的结果。您可以使用LINQ使代码更加简洁和可读。以下示例说明了如何在“签到”和“签退”列中找到最小值,其中这些值晚于给定确认编号的“扫描时间”:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<Record> records = new List<Record>
        {
            new Record { ConfirmationNumber = 500012, ClockIn = TimeSpan.Parse("08:00"), ClockOut = TimeSpan.Parse("16:00") },
            new Record { ConfirmationNumber = 500013, ClockIn = TimeSpan.Parse("08:00"), ClockOut = TimeSpan.Parse("11:00") },
            new Record { ConfirmationNumber = 500014, ClockIn = TimeSpan.Parse("10:00"), ClockOut = TimeSpan.Parse("12:00") },
            new Record { ConfirmationNumber = 500015, ClockIn = TimeSpan.Parse("15:00"), ClockOut = TimeSpan.Parse("17:00") }
        };

        int sweepConfirmationNumber = 500013; // The Confirmation Number you want to calculate for
        TimeSpan sweepTime = records.First(r => r.ConfirmationNumber == sweepConfirmationNumber).ClockIn;

        // Filter records that are later than the Sweep Time
        var relevantRecords = records.Where(r => r.ConfirmationNumber != sweepConfirmationNumber && r.ClockIn > sweepTime);

        // Calculate the number of overlapping confirmations
        int overlappingCount = relevantRecords.Count();

        // Find the minimum Clock In time among relevant records
        TimeSpan minClockIn = relevantRecords.Min(r => r.ClockIn);

        // Find the minimum Clock Out time among relevant records
        TimeSpan minClockOut = relevantRecords.Min(r => r.ClockOut);

        // Calculate pro-rata based on the minimum values and overlapping count
        double proRataHours = (minClockOut - minClockIn).TotalHours / overlappingCount;

        Console.WriteLine($"Minimum Clock In: {minClockIn}");
        Console.WriteLine($"Minimum Clock Out: {minClockOut}");
        Console.WriteLine($"Pro-Rata Hours: {proRataHours}");
    }
}

class Record
{
    public int ConfirmationNumber { get; set; }
    public TimeSpan ClockIn { get; set; }
    public TimeSpan ClockOut { get; set; }
}

在这段代码中,我们首先过滤相关记录(晚于“扫描时间”的记录),然后在这些相关记录中找到“上班打卡”和“打卡下班”列中的最小值。最后,我们根据最小值和重叠确认的数量按比例计算小时数。

© www.soinside.com 2019 - 2024. All rights reserved.