如何构建动态数据的树结构? [英] How to build a tree-structure of the data coming dynamically ?

查看:56
本文介绍了如何构建动态数据的树结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从数据库中获取以下字符串数据,它们是Gmail邮箱的标签结构。它们与/运算符配对。字符串在/之前是父级,在/之后是子级。



父母/子女

父母/父母2 /孩子

父母/父母2 /父3 /儿童
父母/父母2 /父母3 /父母4 /孩子

父母/父母2 /父母3 /父母4 /父母5 /儿童..

....... ............................................



以上数据是动态提取的,父/子的名称可以是任意数字,并且可以有任意数量的对。



如何解析所有可能的行并构建树结构?



Hi, I am getting the following string data from the database and they are label structure of Gmail Mailbox. They are paired with "/" operator. The string comes before "/" is parent and which comes after the "/" is a child.

parent/child
parent/parent2/child
parent/parent2/parent3/child
parent/parent2/parent3/parent4/child
parent/parent2/parent3/parent4/parent5/child..
...................................................

This above data is getting extracted dynamically and the names of "parent/child" could be anything, and they can have any number of pairs.

how to parse all the possible lines and build a tree structure ?

foreach(string str in data.strs)
{

}
}

推荐答案

定义树结构的最简单方法之一是使用已经可用的列表实现,例如:

One of the simplest way to define a tree structure is using already available list implementation, for example:
    using NodeList = System.Collections.Generic.List<treenode>;

// ...

    class TreeNode {
        internal string Name { get; set; }
        internal TreeNode[] Children { get { return children; } } 
        NodeList children = new NodeList();
        internal void AddChild(string name) { /* isn't it obvious? */ }
        // ... and so on...
    } //class TreeNode</treenode>





在解析过程中,您需要遍历树并找到匹配的路径,将新子节点添加为之前未添加的节点。



无论如何,这是输入数据中树的非常糟糕的表示。你确定它是给定的,你不能把它变成更好的东西吗?您是否对树操作有所了解?



仅显示属性名称。另一个步骤是使用通用参数:



During parsing, you need to walk the tree and find matching path, adding new children as nodes which haven't been added before.

Anyway, this is a really bad representation of tree in your input data. Are you sure it's given and you cannot change it into anything better? Did you get an idea on tree operations?

The property Name is shown just for example. Another step would be using a generic parameter:

    using System.Collections.Generic;

//...

    class TreeNode<NodeInfo> {
        internal NodeInfo Info { get; set; }
        internal TreeNode<NodeInfo>[] Children { get { return children; } }
        List<TreeNode<NodeInfo>> children = new List<TreeNode<NodeInfo>>();
        internal void AddChild(NodeInfo name) { /* isn't it apparent */ }
        // ... and so on...
    } //class TreeNode





您可能需要向节点类添加树操作,例如插入,删除,搜索,依此类推...



-SA


请记住,只有你才能正常工作'使用增加一级的结构。





string [] data = new string []

{

level1 / l1-child1,

level1 / l1-child2,

level1 / level2 / l2 -child1,

level1 / level2 / l2-child2,

level1 / level2 / level3 / l3-child1,

level1 / level2 / level3 / l3-child2,

};



Keep in mind it only properly works if you're using an structure of levels that increases by one.


string[] data = new string[]
{
"level1/l1-child1",
"level1/l1-child2",
"level1/level2/l2-child1",
"level1/level2/l2-child2",
"level1/level2/level3/l3-child1",
"level1/level2/level3/l3-child2",
};

TreeNode currentNode = null, nextNode = null;
int items_level = 0;
foreach(string dat in data)
{
    string[] items = dat.Split(new char[] { '/' });

    // same level as last string
    //
    if (items_level == items.Length)
    {
        currentNode.Nodes.Add(items[items_level - 1]);
        continue;
    }

    // special case for 1st time
    //
    if (currentNode == null)
    {
        nextNode = treeView1.Nodes.Add(items[0]);
        items_level = 1;
    }
    else
    {
        nextNode = currentNode.Nodes.Add(items[items_level - 1]);
    }

    nextNode.Nodes.Add(items[items_level]);

    items_level = items.Length;
    currentNode = nextNode;
}


为了使这更有趣,我将使用一个项目不是按顺序的数据:
To make this more interesting I'll use data that has one item that is not "in order:"
private string data = @"parent1/child1
parent1/parent1a/child2
parent2/parent2a/parent2a1/parent2a1a/child4
parent1/parent1a/parent1a1/child3
parent2/parent2a/parent2a1/parent2a1a/child4
parent2/parent2a/parent2a1/parent2a1a/parent2a1a1/child5";

请注意此处的假设是Google电子邮件列表邮件类别文件夹路径永远不会有两个不同的节点(在两个不同的根节点内),每个节点都有一个同名的子节点;正是这种约束允许通过使用Dicationary< string,TreeNode>来进行非递归解析。并且,请注意:此代码是几年前编写的;我欢迎任何改进建议。



在此处显示的示例中,数据被解析为填充WinForm TreeView:

Note the assumption made here that the list of Google e-mail category folder-paths will never have two different nodes (within two different root nodes) that each have a sub-node with the same name; it is this constraint that allows non-recursive parsing by using a Dicationary<string, TreeNode>. And, please note: this code was written a few years ago; I welcome any suggestions for improvement.

In the example shown here the data is parsed to populate a WinForm TreeView:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

private Dictionary<string,> dctTokenToTreeNode = new Dictionary<string,>(); 
private TreeNode currentNode;
private TreeNode lastNode;

private string[] parsedLines;
private string[] tokens;
private string lastToken;

private char[] lineSplitChar = new[] { '\n', '\r' };
private char[] nodeSplitChar = new[] { '/' };

private void ParseData(TreeView TV, string data)
{
    string token;

    parsedLines = data.Split(lineSplitChar, StringSplitOptions.RemoveEmptyEntries);

    foreach (string line in parsedLines)
    {
        tokens = line.Split(nodeSplitChar, StringSplitOptions.RemoveEmptyEntries);

        for (int i = 0; i < tokens.Length; i++)
        {
            lastToken = token;

            token = tokens[i];

            if (dctTokenToTreeNode.ContainsKey(token)) continue;
            
            currentNode = new TreeNode(token);

            if (dctTokenToTreeNode.TryGetValue(lastToken, out lastNode))
            {
                lastNode.Nodes.Add(currentNode); 
            }
            else
            {
                TV.Nodes.Add(currentNode);
            }

            dctTokenToTreeNode.Add(token, currentNode);
        }
    }
}


这篇关于如何构建动态数据的树结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆