通过列表迭代以确定元素的层次结构级别

时间:2017-04-07 07:15:48

标签: c# list loops iteration hierarchy

有一个项目列表,其中包含一个名为" HierarchyLevel"的字段。 (字符串的类型),它决定了这样的元素的层次结构:Link to image。 树结构看起来像这样:



<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>
&#13;
&#13;
&#13;

等等。

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

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);
            }
        }
    }
}

但显然这是一个糟糕的方法。 我想获得一些关于如何正确迭代列表的帮助和建议。

1 个答案:

答案 0 :(得分:0)

我们可以使用以下方式实现这一目标:

  • 所有项目的词典(以帮助查找父节点)
  • 根节点列表(如果有超过1个根)
  • 按层次结构深度排序的DBItem对象列表(1.01之前的1)

示例实施:

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