繁体   English   中英

将数字序列转换为父/子层次

[英]Convert number sequence to Parent/Child hierarchy

我正在将CSV文件加载到程序中,该文件是从旧版ERP系统传递来的。 CSV包含多级物料清单(BOM)数据,我最终将需要精简并发送每个唯一的BOM进行处理。 目前,我很努力,因为记录不包含parentID,而是依靠记录的顺序来定义任何类型的父/子关系。 我唯一需要做的就是将Level和SubLevel按设定的顺序进行布局

  • 级别0是根,可以包含1个或多个级别1
  • 级别1是0的子级,并且可以包含0个或多个级别2
  • 级别2是1的子级,可以包含0个或多个级别1
  • 等等...

这是数据的示例,为简化起见,我将其缩写为:

+---------------------------------+  
¦ UniquePartID ¦ Level ¦ SubLevel ¦  
¦--------------+-------+----------¦  
¦ 05468        ¦ 0     ¦ 0        ¦  
¦ 12420        ¦ 1     ¦ 1        ¦  
¦ 08186        ¦ 2     ¦ 1        ¦  
¦ 03926        ¦ 3     ¦ 1        ¦  
¦ 93650        ¦ 2     ¦ 2        ¦  
¦ 07642        ¦ 3     ¦ 1        ¦  
¦ 16569        ¦ 2     ¦ 3        ¦  
¦ 49397        ¦ 1     ¦ 2        ¦  
¦ 93093        ¦ 1     ¦ 3        ¦  
¦ 36250        ¦ 2     ¦ 1        ¦  
+---------------------------------+  

并按层次显示,如下所示:

                            0
            ------------------------
            |           |         | 
            1           1         1 
        ----------              ----
        |    |   |              |   
        2    2   2              2   
        -    -
        |    |
        3    3

我已经将CSV数据加载到类表示中,但是无法找到一种使用“级别/子级别”和文件顺序作为参考可靠地标识父子关系的方法

有人对我有什么建议吗?

只需存储每个级别的最后一个节点。 如果出现条目,则将其插入当前级别减1的存储(最后)节点中,并将其作为子级别的子级插入。 然后,再次将插入的节点存储为其级别的最后一个节点。 这应该可以解决问题。 这是一个例子:

public class Entry
{
    public Entry(int id, int lvl, int sublvl)
    {
        UniquePartID = id;
        Level = lvl;
        SubLevel = sublvl;
    }

    public int UniquePartID;
    public int Level;
    public int SubLevel;
}

public class Node
{
    public int UniquePartID;
    public Node Parent = null;
    public List<Node> Children = new List<Node>();
}

public List<Node> LastLayerNodes = new List<Node>();

public Node BuildHierarchy(List<Entry> entries)
{
    Node root = null;

    foreach (Entry entry in entries)
    {
        Node node = new Node();
        node.UniquePartID = entry.UniquePartID;

        if (entry.Level == 0)
        {
            root = node;
            LastLayerNodes.Add(root);
        }
        else
        {
            node.Parent = LastLayerNodes[entry.Level - 1];
            node.Parent.Children.Add(node);

            if (LastLayerNodes.Count <= entry.Level)
                LastLayerNodes.Add(node);
            else
                LastLayerNodes[entry.Level] = node;
        }
    }

    return root;
}

然后,您可以像这样使用它:

List<Entry> entries = new List<Entry>
{
    new Entry(05468, 0, 0),
    new Entry(12420, 1, 1),
    new Entry(08186, 2, 1),
    new Entry(03926, 3, 1),
    new Entry(93650, 2, 2),
    new Entry(07642, 3, 1),
    new Entry(16569, 2, 3),
    new Entry(49397, 1, 2),
    new Entry(93093, 1, 3),
    new Entry(36250, 2, 1)
};

Node node = BuildHierarchy(entries);

这应该很容易:

class Node {
  public int UniquePartID { get; private set; }
  public int Level { get; private set; }
  public int SubLevel { get; private set; }
  public IList<Node> Children { get; set; }
  public Node Parent { get; set; }
  public Node(int uniquePartID, int level, int subLevel) {
    UniquePartID = uniquePartID;
    Level = level;
    SubLevel = subLevel;
    Children = new List<Node>();
  }

  public override string ToString() {
    return Level.ToString();
  }
}

填充虚拟数据:

  var nodes = new List<Node> {
    new Node(05468, 0, 0),
    new Node(12420, 1, 1),  
    new Node(08186, 2, 1),  
    new Node(03926, 3, 1),  
    new Node(93650, 2, 2),  
    new Node(07642, 3, 1),  
    new Node(16569, 2, 3),  
    new Node(49397, 1, 2),  
    new Node(93093, 1, 3),  
    new Node(36250, 2, 1)
  };

实际代码:

var parent = nodes[0];
for (var i = 1; i < nodes.Count; i++) {
  var node = nodes[i];
  while (node.Level <= parent.Level) {
    parent = parent.Parent;
  }
  parent.Children.Add(node);
  node.Parent = parent;
  parent = node;
}
var root = nodes[0];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM