是否可以减少这个长嵌套for循环以及条件以增加其可读性并优化它以供将来参考。
在为我的调度应用程序编写代码时,我最终得到了如下所示的方法。真的,我有一个像this这样的数据结构。在这里,我检查 - 是否有任何阶段(内部LCycle)同时使用相同的工具,如果找到它,则调用另一个方法LCycleTimeShift
进行重新排列。
但是我想检查新的安排是否具有适应性,并且for循环计数器被重置,以便它将再次检查新的安排。我认为这不是编写代码以获得更好的可读性的更好方法。对该主题的一点研究发现,调查员可以帮助我。但我不知道如何使用以下代码完成此操作。
public List<LCycle> ToolArrangment(List<LCycle> TimeLineInit)
{
for (int i = 0; i < TimeLineInit.Count; i++)//Each LIfeCycles In TimeLine
{
for (int j = 0; j < TimeLineInit[i].Stage.Count; j++)//Each Stages inTimeLine
{
for (int k = 0; k < i; k++)//Each L esvd =ifeCycles Upto Current LifeCycle
{
for (int l = 0; l < TimeLineInit[k].Stage.Count; l++)//Each Stages of (LifeCycle upto current LifeCycle)
{
for (int m = 0; m < TimeLineInit[i].Stage[j].ToolList.Count; m++)//each tools in stage of timelkine
{
for (int n = 0; n < TimeLineInit[k].Stage[l].ToolList.Count;n++ )// Each tools In that stage (for loop outer of outer)
{
if (TimeLineInit[i].Stage[j].ToolList[m].ToolName == TimeLineInit[k].Stage[l].ToolList[n].ToolName)//If both tools are same (satidfying above for loop conditions)
{
if (IsTimeOverLaps(TimeLineInit[i].Stage[j].StageSpan, TimeLineInit[k].Stage[l].StageSpan))
{//tool using at same time.
Stage ReplaceStage = TimeLineInit[i].Stage[j].DeepCopy();//Taking Copy of stage Span to make time shift
Double TimeDifference=(ReplaceStage.StageSpan.ToTime-ReplaceStage.StageSpan.FromTime).TotalMinutes;//Calculating required time shift
ReplaceStage.StageSpan.FromTime=TimeLineInit[k].Stage[l].StageSpan.ToTime;//FromTime changed accordingly
ReplaceStage.StageSpan.ToTime=ReplaceStage.StageSpan.ToTime.AddMinutes(TimeDifference);//To Time Changed accordingly
LCycleTimeShift(TimeLineInit[i], ReplaceStage);//passing refernce
j = 0; k = 0; l = 0; m = 0; n = 0;//Counter Reset to validate the new arrangment
}
}
}
}
}
}
}
}
return TimeLineInit;
}
答案 0 :(得分:2)
尝试使用LINQ,尤其是SelectMany和Join方法
var t = TimeLineInit
.SelectMany(t=>t.Stage)
.SelectMany(s=>s.ToolList);
...
t
.Join(t, [your conditions 1])
.Join(t, [your conditions 2])
答案 1 :(得分:1)
唯一合理的选择是将迭代内容作为方法放在模型中互相调用,这样它就会更易读,也更容易理解。
答案 2 :(得分:1)
在开始沿着这条路前行之前的一些事情。代码现在有效吗?你有单元测试吗?我只是问,因为在开始任何重构之前,如果你有测试用例就很棒。
关于枚举器的主题,一行代码对我很突出:
LCycleTimeShift(TimeLineInit[i], ReplaceStage);//passing refernce
j = 0; k = 0; l = 0; m = 0; n = 0;//Counter Reset to validate the new arrangment
你不允许在枚举操作中修改一个集合,所以你可能会发现你在该函数中所做的任何魔法都适用于(...),它可能不再适用于foreach (...)或LINQ枚举。仅当它正在删除时,才会将其添加到集合中,而这似乎正在执行。我不得不在下面进行一些更改,因为我假设每次传递后枚举都会改变,这意味着我每次都会重新评估重复项。
正如你所说,似乎你想要找到包含同时使用的同一工具的任何两个阶段(不属于同一个LCycle)。然后,您对该阶段的时间进行一些更改,然后修改父级。我感觉合理。这就是我想出的。我没有任何测试用例,但它可能会让你朝着正确的方向前进。
var toolsInUse = TimeLineInit
.SelectMany(cycle => cycle.Stage
.SelectMany(stage => stage.ToolList.Select(tool => new
{
Cycle = cycle,
Stage = stage,
Tool = tool.ToolName
})));
var duplicateUse = toolsInUse.Join(toolsInUse,
x => x.Tool,
x => x.Tool,
(a, b) => new { Use = a, Duplicate = b })
.Where(x => x.Use.Cycle != x.Duplicate.Cycle &&
IsTimeOverLaps(x.Use.Stage.StageSpan, x.Duplicate.Stage.StageSpan));
while (duplicateUse.Count() > 0)
{
var item = duplicateUse.First();
Stage ReplaceStage = item.Use.Stage.DeepCopy();//Taking Copy of stage Span to make time shift
Double TimeDifference = (ReplaceStage.StageSpan.ToTime - ReplaceStage.StageSpan.FromTime).TotalMinutes;//Calculating required time shift
ReplaceStage.StageSpan.FromTime = item.Duplicate.Stage.StageSpan.ToTime;//FromTime changed accordingly
ReplaceStage.StageSpan.ToTime = ReplaceStage.StageSpan.ToTime.AddMinutes(TimeDifference);//To Time Changed accordingly
LCycleTimeShift(item.Use.Cycle, ReplaceStage);//passing refernce
}
我对性能,准确性没有任何要求。这只是为了指出你的方向。我希望它有所帮助。