基于子列表 LINQ 拆分主列表

  • 本文关键字:列表 拆分 LINQ c# list linq
  • 更新时间 :
  • 英文 :


>我有如下列表类。我需要根据List<Activity>数滑List<TimeSheet>。如果活动大于 8,则列表与列表 0-7 和 7 开始拆分为两个子列表。保留值在列表中应相同,例如员工姓名和活动时间。

更多细节:我正在添加更多细节。 时间只有一个条目,但内部活动有 10 个条目。我需要用两个列表拆分时间。首次列表消耗 0-7 个活动,另一个时间列表消耗 8 个以上活动。因此,两个子列表中的员工名称应相同。只有活动列表不同。在新列表中,一个列表有 8 个活动条目,另一个列表有 2 个活动条目。

List<TimeSheet> Time;
сlass TimeSheet
{
public string employeeName {get;set;}
public List<Activity> activity {get;set;}
public List<ActivityHours> ActivityHours{get;set;}
}
class Activity
{
public string Id {get;set;}
public string Activity {get;set;}
}
class ActivityHours
{
public string ActivityId {get;set;}
public string hours {get;set;}
}

如果您不关心 ActivityHours 在不同的活动块中具有相同的引用,您可以使用以下代码:

var newTime = Time
.SelectMany(t =>
Enumerable
.Range(0, (t.activity.Count - 1) / 8)
.Select(i => new TimeSheet
{
employeeName = t.employeeName,
ActivityHours = t.ActivityHours,
activity = t.activity.GetRange(i * 8, Math.Min(8, t.activity.Count))
}))
.ToList();

请注意,Enumerable.Range(0, count)返回类似Enumerable<int>[0, 1,... , count-1]

(t.activity.Count - 1) / 8

是,如果计数是 8 的倍数,则末尾没有具有空活动的时间表。

activity.GetRange(i, count)返回一个计数大小从活动的第 i 个元素开始的Enumerable<Activity>

Math.Min(8, t.activity.Count)是防止争论超出范围。

如果要使它们独立,可以克隆它:

var newTime = Time
.SelectMany(t =>
Enumerable
.Range(0, (t.activity.Count - 1) / 8)
.Select(i => new TimeSheet
{
employeeName = t.employeeName,
ActivityHours = 
(t.activity.Count < 8) ? 
t.ActivityHours : 
t.ActivityHours.Select(h => new ActivityHours
{
ActivityId = h.ActivityId,
hours = h.hours
}).ToList(),
activity = t.activity.GetRange(i * 8, Math.Min(8, t.activity.Count))
}))
.ToList();

follwing 也在做这项工作,但方式与 @Bizhan 的解决方案不同

List<TimeSheet> SplitList = 
TimeList.Aggregate(new List<TimeSheet>(), 
(accList, timeSheet) =>
{
if ((timeSheet.Activities?.Count ?? 0) > 8)
{
accList.Add(new TimeSheet 
{ 
EmployeeName = timeSheet.EmployeeName, 
ActivityHours = timeSheet.ActivityHours.ToList(), 
Activities = timeSheet.Activities.GetRange(0, 8) 
});
accList.Add(new TimeSheet 
{ 
EmployeeName = timeSheet.EmployeeName, 
ActivityHours = timeSheet.ActivityHours, 
Activities = timeSheet.Activities.GetRange(8, timeSheet.Activities.Count - 8) 
});
}
else
{
accList.Add(timeSheet);
}
return accList;
},
accList => accList);

这似乎很简单,Take()Skip()

List<TimeSheet> result = 
Time
.SelectMany(t => new []
{
new TimeSheet()
{
employeeName = t.employeeName,
activity = t.activity.Take(8).ToList(),
ActivityHours = t.ActivityHours,
},
new TimeSheet()
{
employeeName = t.employeeName,
activity = t.activity.Skip(8).ToList(),
ActivityHours = t.ActivityHours,
},
})
.Where(t => t.activity.Any())
.ToList();

相关内容

  • 没有找到相关文章

最新更新