-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

あなたがその道を進み始める前にいくつかのこと。コードは現在機能していますか?ユニットテストはありますか?リファクタリングを開始する前に、テストケースがあると便利だからです。

列挙子のトピックについては、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列挙。これは、コレクションにアイテムを削除、追加している場合にのみ当てはまります。パスごとに列挙が変更されると想定しているため、以下でいくつか変更を加える必要がありました。これは、重複を毎回再評価することを意味します。

あなたが言ったように、同時に使用されている同じツールを含む任意の2つのステージ(同じ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 に答える