-1

是否可以减少这种长嵌套的 for 循环和 if 条件以增加其可读性并对其进行优化以供将来参考。

在为我的日程安排应用程序编写代码时,我最终得到了如下所示的方法。真的,我有这样的数据结构。在这里,我检查 - 是否有任何阶段(在 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;
}
4

3 回答 3

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])
于 2013-03-24T09:48:58.473 回答
1

唯一合理的选择是将迭代的东西作为方法放在你的模型中相互调用,这样它就会更具可读性,也更容易理解。

于 2013-03-24T09:48:52.407 回答
1

在你开始走那条路之前做一些事情。代码现在工作了吗?你有单元测试吗?我只问是因为在开始任何重构之前,如果您有测试用例,那就太好了。

关于枚举数的话题,有一行代码让我印象深刻:

LCycleTimeShift(TimeLineInit[i], ReplaceStage);//passing refernce
j = 0; k = 0; l = 0; m = 0; n = 0;//Counter Reset to validate the new arrangment

您不允许在枚举操作中修改集合,因此您可能会发现无论您在该函数中执行的任何魔术都可以与 for(...) 一起正常工作,但它可能不再适用于 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
}

我对性能和准确性不做任何声明。这只是为您指明一个方向。我希望它有所帮助。

于 2013-03-24T10:54:13.483 回答