代码之家  ›  专栏  ›  技术社区  ›  Daniel Žeimo

如何在递归迭代对象子对象时仅在找到特定值后添加数据

  •  0
  • Daniel Žeimo  · 技术社区  · 7 年前

    IDictionary<int,Division> 其中int是对象的深度,如下所示。

    字典结果示例:

    0, Parent
    1, Parent.Child
    2, Parent.Child.Child
    
    
    class Division
        {
            public int Id { get; set; }
            public int ParentId { get; set; }
    
            public Division Parent { get; set; }
            public ICollection<Division> Children { get; set; }
        }
    

    我使用递归从根父级迭代到所需的子级,同时向字典添加深度和除法。 对于迭代,我使用这个方法。

           public void GetBranchFromTop(Division division, int selectedNodeId, int selectedNodeDepth, ref IDictionary<int, Division> branch)
            {
                branch.Add(selectedNodeDepth, division);
    
                if (division.Id == selectedNodeId)
                {               
                    return;
                }
    
                if (division.Children != null)
                {
                    foreach (var child in division.Children)
                    {
                        selectedNodeDepth = selectedNodeDepth + 1;
                        GetBranchFromTop(child, selectedNodeId, selectedNodeDepth, ref branch);
                    }
                }
            }
    

    当对象只有一个子对象时,此方法可以正常工作。当有更多的孩子加入字典是不可能的,因为深度键是重复的。
    我想,只有在找到我正在搜索的对象之后,我才需要将对象添加到字典中,但我想不出如何递归地进行添加。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Alex Buyny    7 年前

    我可以想出两种方法。首先,你需要有一个单独的 branch GetBranchFromTop ,像这样

    public void GetBranchFromTop(
        Division division, 
        int selectedNodeId, 
        int selectedNodeDepth, 
        ref IDictionary<int, Division> foundBranch, 
        IDictionary<int, Division> currentBranch)
    {
        if(foundBranch != null){
          return; //no need to continue search if the target branch was found already
        }
        currentBranch.Add(selectedNodeDepth, division);
    
        if (division.Id == selectedNodeId)
        {               
           foundBranch = currentBranch;
           return;
        }
    
        if (division.Children != null)
        {
            var nextNodeDepth = selectedNodeDepth + 1;//note this is moved out of the loop
            foreach (var child in division.Children)
            {
    
                var newBranch = new Dictionary<int, Division>(currentBranch); //copy the branch for each child.
                GetBranchFromTop(child, selectedNodeId, nextNodeDepth, ref foundBranch, newBranch);
          }
       }
    }
    

    selectedNodeDepth = selectedNodeDepth + 1; -它在循环中,这意味着它将对所有处于相同位置的子对象递增 +1 深度

    Division targetDivision . 当你有了它,用 Parent

    List<Division> parentsAndSelf = new List<Division>();
    Division currentDivision = targetDivision;
    while(currentDivision != null){
      parentsAndSelf.Add(currentDivision);
      currentDivision = currentDivision.Parent;
    }
    parentsAndSelf = parentsAndSelf.Reverse();
    

    现在 parentsAndSelf 列表将包含所需的 Parent -> Child -> Child.Child 列出目标 分开 最后。深度将是列表中项目的索引。