我正在为以下方面寻找一个好的设计/算法/模式:
我有一大堆TODO任务。他们每个人都有一个估计的持续时间。我想将较大的列表分成较小的子列表,每个子列表包含最多4小时的工作。
我目前的算法是这样的:
while( index < list.Count )
{
List<string> subList = CreateSublist( ref index );
SaveSubList(subList);
}
将索引作为ref传递感觉很尴尬,而不是OOD。我真的很喜欢TODO列表,有点像流,所以我想知道我能做些类似的东西,但我有点像C#新手。我目前也仅限于C#2.0。有关优秀设计的快速指示吗?
答案 0 :(得分:2)
你可以用一种方法填充所有内容:
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;
}
或者,使用迭代器:
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;
}
答案 1 :(得分:0)
这应该做的工作:
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),这似乎是最直接的解决方案。
答案 2 :(得分: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);
}
答案 3 :(得分: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;
}
请注意,这不是最佳解决方案......这将达到一个全新的水平:)