我们有一个第三方工作流程系统,其中包含以下列格式存储为平面文件的操作的分层列表:
等...
在每个节点下面是一个属性列表,这个项目的目的是编写一个小程序,它将遍历每个文件,从根节点关系构建层次结构,然后我们就可以使用这个模型来运行报告数据。
到目前为止,我的尝试是创建一个Node类,其中包含Child
类型的List<Node>
属性,它将存储层次结构
我正在努力弄清楚如何确定哪个节点应该是哪个节点的子节点。我当前的过程是捕获先前的节点名称,如果当前节点名称包含前一个节点名称,它必须是一个子节点,但我发现当它有几个节点深时,它就变成了flakey。
有没有人建议以更可靠的方式描述这些关系?
答案 0 :(得分:1)
这样的事情应该有效:
public class Node
{
public string Key { get; set; }
public Node Parent { get; set; }
public IList<Node> Children { get; set; }
}
private Node LoadAll(string[] keys)
{
var nodes = new Dictionary<string, Node>(StringComparer.OrdinalIgnoreCase);
var orphanNodes = new List<Node>();
Node root = null;
foreach (var key in keys)
{
var node = new Node()
{
Key = key
};
nodes[key] = node;
int keySeparator = key.LastIndexOf("-");
if (keySeparator != -1)
{
string parentKey = key.Substring(0, keySeparator);
if (nodes.TryGetValue(parentKey, out var parentNode))
{
if (parentNode.Children == null)
{
parentNode.Children = new List<Node>();
}
node.Parent = parentNode;
parentNode.Children.Add(node);
}
else
{
orphanNodes.Add(node);
}
}
else if (root != null)
{
throw new Exception("Root node already exists.");
}
else
{
root = node;
}
}
foreach (var orphan in orphanNodes)
{
string parentKey = orphan.Key.Substring(0, orphan.Key.LastIndexOf("-"));
if (nodes.TryGetValue(parentKey, out var parentNode))
{
if (parentNode.Children == null)
{
parentNode.Children = new List<Node>();
}
orphan.Parent = parentNode;
parentNode.Children.Add(orphan);
}
else
{
throw new Exception("Nodes without parents found.");
}
}
return root;
}
它维护所有节点(nodes
)及其键的列表,以便可以轻松地从其键中查找任何节点。它还维护了一个节点列表,我们在初始循环中没有任何父节点(orphanNodes
- 如果父节点总是在子节点之前,则可以删除它。)
对于每个键我们:
如果在子节点之后加载了任何父节点,我们将为每个孤儿执行以下操作:
可能会改进某些字符串操作,但这是一种可以解决问题的方法。