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

时间:2014-10-30 08:28:31

标签: c# linq

我试图将每天进出时间记录列表合并到可能的最小记录数。

到目前为止,我所做的是将这些行分成他们需要进入的组,并将进出时间列入每天的列表中。

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

我坚持使用的是在处理完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;

3 个答案:

答案 0 :(得分:3)

使用List.RemoveAt Method之类的东西,如myList.RemoveAt(0)将删除列表中的第一项

答案 1 :(得分: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上应用开关并仅初始化相关属性。在这种情况下,您应该声明一个私有类,而不是您当前使用的匿名类型,以便将信息从方法传递到另一个。

答案 2 :(得分:0)

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

false