2017-04-07 59 views
0

有一个项目列表包含名为“HierarchyLevel”(类型字符串),它决定了像这样的元素的层次结构:Link to image。 树结构是这样的:迭代throuh列表以确定元素的层次结构级别

<ul> 
 
<li>1</li> 
 
<ul> 
 
<li>1.01</li> 
 
<ul> 
 
<li>1.01.01</li> 
 
<li>1.01.02</li> 
 
</ul> 
 
<li>1.02</li> 
 
<ul> 
 
<li>1.02.01</li> 
 
</ul> 
 
<li>1.03</li> 
 
</ul> 
 
<ul>

等。

我的目标是实现一个包含每个元素的父项和子项的信息的类。 到目前为止,我有这个类:

class TreeNode<DBItem> 
{ 
    public DBItem Value { get; private set; } 
    public List<TreeNode<DBItem>> Children = new List<TreeNode<DBItem>>(); 
    public TreeNode<DBItem> Parent { get; private set; } 

    public string Level { get; private set; } 

    public TreeNode (DBItem item, string level) 
    { 
     this.Value = item; 
     this.Level = level; 
    } 

    public TreeNode<DBItem> this[int i] 
    { 
     get { return this.Children[i]; } 
    } 

    public TreeNode<DBItem> AddChild(DBItem item, string level) 
    { 
     TreeNode<DBItem> node = new TreeNode<DBItem>(item, level) { Parent = this }; 
     this.Children.Add(node); 
     return node; 
    } 
} 

问题是,我不太明白如何通过项目的集合迭代。我试过这个:

TreeNode<DBItem> parent = new TreeNode<DBItem>(neededItems[0], "1"); 
foreach (var doc in neededItems) 
{ 
    string level = doc.GetStringValue("HierarchyLevel"); 
    if (level.StartsWith("1.")&& level.Length < 5) 
    { 
     var child1 = parent.AddChild(doc, level); 
     foreach (var child in neededItems) 
     { 
      string level1 = child.GetStringValue("HierarchyLevel"); 
      if (level1.StartsWith("1."+level)) 
      { 
       child1.AddChild(child, level1); 
      } 
     } 
    } 
} 

但显然这是一个坏的方法。 我想得到一些关于如何正确遍历列表的帮助和建议。

+0

该代码对我来说并不坏。但整个数据结构可以重新设计,您是否可以控制所有设计? –

+0

不幸的是没有。我必须与此合作。给定不良数据结构的 –

+0

,算法不够优雅是合理的。 –

回答

0

我们可以通过实现这一目标:

  • 所有项目的解释(帮助查找父节点)
  • 根节点的列表(如果有多于1根)
  • 由层级深度(11.01)之前订购DBItem对象的列表

样品实施:

class so43271922 
{ 
    public so43271922() 
    { 
    } 

    [DebuggerDisplay("HierarchyLevel = {HierarchyLevel}")] 
    public class DBItem 
    { 
     public string Name { get; private set; } 
     public string HierarchyLevel { get; private set; } 

     public DBItem(string name, string hierarchyLevel) 
     { 
      this.Name = name; 
      this.HierarchyLevel = hierarchyLevel; 
     } 
    } 

    // Dummy list of DB Item objects 
    public readonly DBItem[] listItems = new DBItem[] { 
     new DBItem("Element 1", "1"), 
     new DBItem("Element 1.01", "1.01"), 
     new DBItem("Element 1.01.01", "1.01.01"), 
     new DBItem("Element 1.01.02", "1.01.02"), 
     new DBItem("Element 1.02", "1.02"), 
     new DBItem("Element 1.02.01", "1.02.01"), 
     new DBItem("Element 1.03", "1.03") 
    }; 

    [DebuggerDisplay("HierarchyLevel = {Value.HierarchyLevel}")] 
    public class Node 
    { 
     public static IReadOnlyDictionary<string,Node> AllNodes { get { return allNodes; } } 
     public static IReadOnlyCollection<Node> Roots { get { return roots; } } 

     /// <summary> 
     /// Stores references to all nodex, using HierarchyLevel as key 
     /// </summary> 
     private static Dictionary<string, Node> allNodes = new Dictionary<string, Node>(); 
     /// <summary> 
     /// Stores references to root nodes 
     /// </summary> 
     private static List<Node> roots = new List<Node>(); 



     public DBItem Value { get; private set; } 
     public Node Parent { get; private set; } 
     public List<Node> Children { get; private set; } 

     public int Level { get; private set; } 

     public Node(DBItem li) 
     { 
      this.Children = new List<Node>(); 
      this.Value = li; 
      allNodes.Add(li.HierarchyLevel, this); 

      if (li.HierarchyLevel.Contains(".")) 
      { 
       var parentHier = li.HierarchyLevel.Substring(0, li.HierarchyLevel.LastIndexOf(".")); 
       this.Parent = allNodes[parentHier]; 
       this.Parent.Children.Add(this); 
       this.Level = this.Parent.Level + 1; 
      } 
      else 
      { 
       roots.Add(this); 
       this.Parent = null; 
       this.Level = 0; 
      } 
     } 
    } 

    public void generateHierarchy() 
    { 
     // Sort all items by: hierarchy depth, then by hierarchy level value 
     var sortedItems = listItems 
      .OrderBy(i => i.HierarchyLevel.Count(c => c == '.')); // 1 before 1.01 

     foreach (var item in sortedItems) 
     { 
      new Node(item); 
     } 

     var hier = Node.Roots; 
    } 

} 

Hierarchy Levels in QuickWatch

相关问题