如何从linq查询中删除第一个元素

本文关键字:删除 第一个 元素 查询 linq | 更新日期: 2023-09-27 18:28:20

我试图将每天进出次数的记录列表合并到尽可能少的记录数。

到目前为止,我所做的是将行分组到他们需要加入的组中,并将每天的进出时间放在一个列表中。

然后我想处理列表,将第一组输入和输出行添加到一行上,然后处理下一个条目,创建一行新行或填补前一行的空白。

我坚持的比特是在我处理完linq结果后从它中删除第一个项目

很高兴能以不同的方式来做这件事。

这是我的

       List<LoginRecordLine> condensedLoginRecordLines = new List<LoginRecordLine>();
       List<LoginRecordLine> currentLoginRecordLines = GetLoginRecordsForLoginRecordReport(lowerDate, upperDate, sageDatabaseID, loggedInUserID);
        var groupedLines = from LoginRecordLine line in currentLoginRecordLines
                           group line by new { line.TimesheetID, line.WorkPatternPayRateID } into g
                           select new
                           {
                               Lines = g,
                               TimesheetID = g.Key.TimesheetID,
                               PayRateID = g.Key.WorkPatternPayRateID
                           };
        foreach (var g in groupedLines)
        {
            var monTimes = from line in g.Lines
                           orderby line.MonTimeIn ascending
                           where line.MonTimeSpan != TimeSpan.Zero
                           select new
                           {
                               TimeIn = line.MonTimeIn,
                               TimeOut = line.MonTimeOut,
                               Timesheet = line.Timesheet,
                               PayRate = line.WorkPatternPayRate
                           };
            var tueTimes = //Same as monday
            var wedTimes = //Same as monday
            var thuTimes = //same as monday
            var friTimes = //same as monday
            var satTimes = //same as monday
            var sunTimes = //same as monday

            while (monTimes.Count() != 0 || tueTimes.Count() != 0 || wedTimes.Count() != 0 || thuTimes.Count() != 0 || friTimes.Count() != 0 || satTimes.Count() != 0 || sunTimes.Count() != 0)
            {
                LoginRecordLine condensedLine = new LoginRecordLine();
                if (monTimes.Count() >0)
                {
                    condensedLine.MonTimeIn = monTimes.First().TimeIn;
                    condensedLine.MonTimeOut = monTimes.First().TimeOut;
                    condensedLine.Timesheet = monTimes.First().Timesheet;
                    condensedLine.WorkPatternPayRate = monTimes.First().PayRate;
                    //*************** REVELANT PART *************/
                    //remove first item from monday list
                }
                // tue 
                // wed
                // etc
            }
        }
        return condensedLoginRecordLines;

更新-工作代码-在性能更改之前

 List<LoginRecordLine> condensedLoginRecordLines = new List<LoginRecordLine>();
                List<LoginRecordLine> currentLoginRecordLines = GetLoginRecordsForLoginRecordReport(lowerDate, upperDate, sageDatabaseID, loggedInUserID);
                var groupedLines = from LoginRecordLine line in currentLoginRecordLines
                                   group line by new { line.TimesheetID, line.WorkPatternPayRateID } into g
                                   select new
                                   {
                                       Lines = g,
                                       TimesheetID = g.Key.TimesheetID,
                                       PayRateID = g.Key.WorkPatternPayRateID
                                   };
                foreach (var g in groupedLines)
                {
                    var monTimes = (from line in g.Lines
                                    orderby line.MonTimeIn ascending
                                    where line.MonTimeSpan != TimeSpan.Zero
                                    select new
                                    {
                                        TimeIn = line.MonTimeIn,
                                        TimeOut = line.MonTimeOut,
                                        Timesheet = line.Timesheet,
                                        PayRate = line.WorkPatternPayRate
                                    }).ToList();
            var tueTimes = //Same as monday
            var wedTimes = //Same as monday
            var thuTimes = //same as monday
            var friTimes = //same as monday
            var satTimes = //same as monday
            var sunTimes = //same as monday
                    while (monTimes.Count != 0 || tueTimes.Count != 0 || wedTimes.Count != 0 || thuTimes.Count != 0 || friTimes.Count != 0 || satTimes.Count != 0 || sunTimes.Count != 0)
                    {
                        LoginRecordLine condensedLine = new LoginRecordLine();
                        if (monTimes.Count >0)
                        {
                            condensedLine.MonTimeIn = monTimes.First().TimeIn;
                            condensedLine.MonTimeOut = monTimes.First().TimeOut;
                            condensedLine.Timesheet = monTimes.First().Timesheet;
                            condensedLine.WorkPatternPayRate = monTimes.First().PayRate;
                            condensedLoginRecordLines.Add(condensedLine);
                            monTimes.RemoveAt(0);
                        }
                        //etc
                    }
                }
                return condensedLoginRecordLines;

如何从linq查询中删除第一个元素

使用List.RemoveAt方法,类似于myList。RemoveAt(0)将删除列表的第一项

您应该修改您的算法,也许还应该修改数据结构。

对于查询中的匿名类型,我会添加DayOfWeek属性,因此查询看起来像:

var monTimes = from line in g.Lines
                       orderby line.MonTimeIn ascending
                       where line.MonTimeSpan != TimeSpan.Zero
                       select new
                       {
                           TimeIn = line.MonTimeIn,
                           TimeOut = line.MonTimeOut,
                           Timesheet = line.Timesheet,
                           PayRate = line.WorkPatternPayRate,
                           WeekDay = DayOfWeek.Monday
                       };

然后,最后一个循环将被类似的东西取代:

var condensedLoginRecordLines = monTimes
   .Concat(tueTimes)
   .Concat(wedTimes)
   ..//etc
   .Select(data => new CondensedLine { WeekDay = data.WeekDay, /* here all the properties are initialized */ })
   .ToList();

仅此而已。

如果您仍然喜欢使用MonInTime、TueInTime等属性,请将CondensedLine的创建移到一个单独的函数中,该函数在WeekDay上应用开关并仅初始化相关属性。在这种情况下,您应该声明一个私有类,而不是当前使用的匿名类型,以便将信息从方法传递到另一个方法。

我遇到了类似的问题。在我的例子中,源数据是一个解析为字符串的CSV文件,我想在处理之前删除标题信息。我本可以使用强制转换到列表并删除第一个条目的方法,但我发现可以向where查询添加第二个参数,从而为您提供行号索引。这也适用于IQueryable和IEnumerable重载。

public static List<string> GetDataLinesFromCSV(string csv)
{
    var csvLines = csv.Split(new[] { "'r'n", "'r", "'n" }, StringSplitOptions.RemoveEmptyEntries);
    var dataLines = csvLines.AsQueryable().Where((x, idx) => idx > 0).ToList();
    return dataLines;
}