2017-04-07 41 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

相關問題