>我有如下列表类。我需要根据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();