2009-05-12 6 views
2

からサブリストを作成する私は、次のために良いデザイン/ alogrithm /パターンを探しています:C#2.0デザイン質問 - 大きなリスト

私はTODOタスクの大規模なリストを持っています。それらの各々は、推定期間を有する。大きなリストを小さなサブリストに分割したいと思います。それぞれのサブリストには最大4時間の作業が含まれています。

while(index < list.Count) 
{ 
    List<string> subList = CreateSublist(ref index); 
    SaveSubList(subList); 
} 

refは不便ではないOODを感じているように、インデックスを渡す:

私の現在のアルゴリズムでは、このようなものです。私はストリームのようにTODOリストを実際に消費しているので、私ができることがあれば似ているのだろうかと思っていますが、C#初心者です。私は現在もC#2.0に限定されています。ここでいいデザインのすばらしい指針はありますか?

+0

.NET 2.0またはC#言語仕様2に限定されていますか? –

答えて

2

あなたは一つの方法ですべてを詰め込むことができます。これは、仕事をする必要があります

IEnumerable<List<TodoTask>> GetTodoTasks(IEnumerable<TodoTask> tasks, int timeWindow) 
{   
    List<TodoTask> tasks = new List<TodoTask>(); 
    int duration = 0; 

    foreach(TodoTask task in tasks) 
    { 
     if(duration > timeWindow) 
     { 
      yield return tasks; 

      duration = 0; 
      tasks = new List<TodoTask>(); 
     } 

     tasks.Add(task); 
     duration += task.Duration; 
    } 

    yield return tasks; 
} 
+0

ああ、あなたは私にそれを打つ。私のソリューションとほぼ同じです! – Noldorin

+0

ちょうど何かを見つけました:アイテムをリストに追加した後の継続時間*を増やします。つまり、現在のアイテムの持続時間が* 4時間を超えると、新しいサブリストが作成されます。 askerが欲しい。 – Noldorin

0

List<List<TodoTask>> GetTodoTasks(IEnumerable<TodoTask> tasks, int timeWindow) 
{ 
    List<List<TodoTask>> allTasks = new List<List<TodoTask>>(); 

    List<TodoTask> tasks = new List<TodoTask>(); 
    int duration = 0; 

    foreach(TodoTask task in tasks) 
    { 
     if(duration > timeWindow) 
     { 
      allTasks.Add(tasks); 

      duration = 0; 
      tasks = new List<TodoTask>(); 
     } 

     tasks.Add(task); 
     duration += task.Duration; 
    } 

    allTasks.Add(tasks);   
    return allTasks; 
} 

または、イテレータを使用して

public static List<List<Task>> SplitTaskList(List<Task> tasks) 
{ 
    List<List<Task>> subLists = new List<List<Task>>(); 
    List<Task> curList = new List<Task>(); 
    int curDuration; // Measured in hours. 

    foreach (var item in tasks) 
    { 
     curDuration += item.Duration; 
     if (curDuration > 4) 
     { 
      subLists.Add(curList); 
      curList = new List<Task>(); 
      curDuration = 0; 
     } 

     curList.Add(item); 
    } 

    subLists.Add(curList); 

    return subLists; 
} 

LINQは、おそらく物事を単純化します、しかし、あなたはC#2.0を使っているので(これはおそらく.NET 2.0と推定されます)、これは最も単純なsolutiのように思えますに。

0

これをクラスにカプセル化することをお勧めします。

SubListBuilder<WorkItem> slb = new SubListBuilder<WorkItem>(
    workItems, sublist => sublist.Sum(item => item.Duration) <= 4); 

サブリストの作成方法を制御するための述語を提供できます。それでは、結果だけを得ることができます。

while (slb.HasMoreSubLists) 
{ 
    SaveList(slb.GetNextSubList()); 
} 

これは多分、この方法です。ここで

foreach (var subList in slb.GetSubLists()) 
{ 
    SaveList(subList); 
} 
0

は私のソリューションです:これは最適解決策ではないことを

class Task 
    { 
     public string Name { get; set; } 
     public int Duration { get; set; } 
    } 

    class TaskList : List<Task> 
    { 
     public int Duration { get; set; } 

     public void Add(Task task, int duration) 
     { 
      this.Add(task); 
      Duration += duration; 
     } 
    } 

    private static IList<TaskList> SplitTaskList(IList<Task> tasks, int topDuration) 
    { 
     IList<TaskList> subLists = new List<TaskList>(); 
     foreach (var task in tasks) 
     { 
      subLists = DistributeTask(subLists, task, topDuration); 
     } 
     return subLists; 
    } 

    private static IList<TaskList> DistributeTask(IList<TaskList> subLists, Task task, int topDuration) 
    { 
     if (task.Duration > topDuration) 
      throw new ArgumentOutOfRangeException("task too long"); 

     if (subLists.Count == 0) 
      subLists.Add(new TaskList()); 

     foreach (var subList in subLists) 
     { 
      if (task.Duration + subList.Duration <= topDuration) 
      { 
       subList.Add(task, task.Duration); 
       return subLists; 
      } 
     } 

     TaskList newList = new TaskList(); 
     newList.Add(task, task.Duration); 
     subLists.Add(newList); 
     return subLists; 
    } 

お知らせ...それは全く新しいレベルに行くだろう:)

また、このソリューションを意志アイテムをNoldorinAntonのソリューションより少し上手く配布してください。最終的にはリストが少なくなるかもしれません。