如何从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;
使用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;
}