首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归统计任务的子任务

递归统计任务的子任务
EN

Stack Overflow用户
提问于 2020-04-10 04:35:44
回答 2查看 27关注 0票数 0

我如何计算一个任务的子任务,并计算其中有多少任务已经完成?任何子任务都可以有多个子任务,我们应该只在最低级别计算任务的子任务(没有更多的子任务)。(当一个任务的所有子任务都完成时,该任务就是就绪的。但这只是解释,所有的任务都知道它们是否准备好了)

代码语言:javascript
复制
Task1             (not done)
  SubTask1a        (not done)
     SubTask1a_1  (done)       <-- lowest level
     SubTask1a_2  (not done)   <-- lowest level
  SubTask1b       (not done)   <-- lowest level

因此,在本例中,Task1有3个SubTasks,但只完成了一个。

我设法迭代了所需的项,但无法计算子任务的总和以及其中有多少任务已完成。

代码语言:javascript
复制
var tasks = new List<Task>()
            {
                new Goal(){ Id=1, Name="Task1" ,ParentId=0, Done=false},
                new Goal(){ Id=2, Name="SubTask1a" ,ParentId=1, Done=false},
                new Goal(){ Id=3, Name="SubTask1a_1" ,ParentId=2, Done=true},
                new Goal(){ Id=4, Name="SubTask1a_2" ,ParentId=2, Done=false},
                new Goal(){ Id=5, Name="SubTask1b" ,ParentId=1, Done=false},
            };
Walk(1);

void Walk(int Id)
{
  var children = goals.Where(c => c.ParentId.Equals(Id)).ToList();
  foreach (var item in children)
  {
    Walk(item.Id);
  }
}
EN

回答 2

Stack Overflow用户

发布于 2020-04-10 04:46:13

这样怎么样?

代码语言:javascript
复制
  bool Done(Goal goal)
  {
    var children = goals.Where(c => c.ParentId.Equals(goal.Id)).ToList();
    if (children.Count == 0)
    {
      return goal.Done;
    }
    else
    {
      int itemCount = 0;
      int doneCount = 0;
      foreach (var item in children)
      {
        itemCount++;
        if (Done(item))
          doneCount++;
      }
      return (doneCount == itemCount);
    }
  }
票数 0
EN

Stack Overflow用户

发布于 2020-04-10 05:18:09

此解决方案将为您提供目标列表中每个目标的待定和已完成最低级别目标的数量。代码中有更多注释。

代码语言:javascript
复制
// Helper class that will contain the number of lowest level goals that are either done or pending.
class Status
{
    public int Done { get; set; }
    public int Pending { get; set; }
}

var statuses = new Dictionary<int, Status>();
Walk(goals);
// Now statuses will contain an entry for each goal. And each status will containthe amount of lowest level goals that still need to be completed to complete that goal.

void Walk(IEnumerable<Goal> goals)
{
    foreach (var goal in goals)
    {
        Walk(child);
    }
}

void Walk(Goal goal)
{
    if (statuses.TryGetValue(goal.Id, out Status status)
    {
        // Already walked this goal.
        return;
    }

    var status = new Status();
    var children = goals.Where(c => c.ParentId.Equals(Id)).ToList();
    if (children.Count == 0)
    {
        // This is a lowest level goal. Create a done or pending status.
        status.Done = goal.Done ? 1 : 0;
        status.Pending = status.Done ? 0 : 1;
    }
    else
    {
        // Make sure we've got the statuses of all children.
        Walk(children);
        var childrenIds = children.Select(c => c.Id).ToList();
        foreach (var childStatus in statuses.Where(s => childrenIds.Contains(s.Key))
        {
            // Update the current status with the children's statuses
            status.Done += childStatus.Done;
            status.Pending += childStatus.Pending;
        }
    }

    statuses.Add(goal.Id, status);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61129791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档