首页 > 解决方案 > 创建对象的递归列表 C#

问题描述

嗨,我有这样的课:

public class Node
{
    public Node();

    public long NodeId { get; set; }

    public int? LevelId { get; set; }

    public ICollection<Node> Children { get; set; }
}

我设法将孩子递归地添加到孩子身上。现在,打印数据是个问题。

从这里引用:递归列表展平 返回一个展平的列表。

private IEnumerable<Node> GetNodes()
{
  // Create a 3-level deep hierarchy of nodes
  Node[] nodes = new Node[]
    {
      new Node 
      { 
        NodeId = 1, 
        LevelId = 1, 
        Children = new Node[]
        {
          new Node { NodeId = 2, LevelId = 2, Children = new Node[] {} },
          new Node
          {
            NodeId = 3,
            LevelId = 2,
            Children = new Node[]
            {
              new Node { NodeId = 4, LevelId = 3, Children = new Node[] {} },
              new Node { NodeId = 5, LevelId = 3, Children = new Node[] {} }
            }
          }
        }
      },
      new Node { NodeId = 6, LevelId = 1, Children = new Node[] {} }
    };
  return nodes;
}

但是,需要这种格式的数据。例子。

NodeId | LevelId | ChildNodeId | ChildLeveld | ChildNodeId | ChildLevelId 
1      | 1       | 2           |  2
1      | 1       | 3           |  2          | 4           | 3
1      | 1       | 3           |  2          | 5           | 3

像:

目前我有一个带有 nodeid 和 levelid 的课程。如何动态创建其他子节点并作为对象集合返回。

public Class New Class 
{
  public int NodeId {get;set;}
  public int LevelId {get;set;}
  public Dictionary<string, object> {get;set;}

  // create dynamic childId and levelId in the dictionary
}

标签: c#linq

解决方案


您的叶节点应该为 null 而不是空列表,因此您可以测试 null 而不是计数为零。您也不需要为每个级别添加列。请参阅下面的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;

namespace ConsoleApplication4
{
    class Program
    {

        static void Main(string[] args)
        {
            Node root = new Node();
            root.setRoot();
            root.BuildTable();
            root.PrintTable();
            Console.ReadLine();
        }
    }
    public class Node
    {
        DataTable dt = new DataTable();
        int maxDepth = 0;
        List<Node> nodes { get; set; }
        public long NodeId { get; set; }
        public int LevelId { get; set; }
        public List<Node> Children { get; set; }

        public void setRoot()
        {
            nodes = GetNodes().ToList();
        }
        public void GetMaxDepth()
        {
            maxDepth = GetMaxDepthRecursive(nodes, 0);
        }
        public int GetMaxDepthRecursive(List<Node> nodes, int depth)
        {
            int returnDepth = depth + 1;
            foreach (Node child in nodes)
            {
                if (child.Children != null)
                {
                    int newDepth = GetMaxDepthRecursive(child.Children, depth + 1);
                    if (newDepth > returnDepth) returnDepth = newDepth;
                }
            }
            return returnDepth;
        }


        private IEnumerable<Node> GetNodes()
        {
            // Create a 3-level deep hierarchy of nodes
            Node[] nodes = new Node[]
            {
                new Node 
                { 
                    NodeId = 1, 
                    LevelId = 1, 
                    Children = new List<Node>()
                    {
                        new Node { NodeId = 2, LevelId = 2, Children = null },
                        new Node
                        {
                            NodeId = 3,
                            LevelId = 2,
                            Children = new List<Node>()
                            {
                                new Node { NodeId = 4, LevelId = 3, Children = null },
                                new Node { NodeId = 5, LevelId = 3, Children = null }
                            }
                        }
                    }
                },
              new Node { NodeId = 6, LevelId = 1, Children = null }
            };
            return nodes;
        }
        public void GetTableRowsRecursive(List<Node> nodes, List<KeyValuePair<int,long>> parents)
        {
            string columnName = "";
            foreach (Node node in nodes)
            {
                if (node.Children == null)
                {
                    DataRow newRow = dt.Rows.Add();
                    if (parents != null)
                    {
                        foreach (KeyValuePair<int, long> parent in parents)
                        {
                            columnName = string.Format("Level {0} Node ID", parent.Key.ToString());
                            newRow[columnName] = parent.Value;
                        }
                    }
                    columnName = string.Format("Level {0} Node ID", node.LevelId);
                    newRow[columnName] = node.NodeId;
                }
                else
                {
                    List<KeyValuePair<int, long>> newParents = new List<KeyValuePair<int, long>>();
                    if(parents != null) newParents.AddRange(parents);
                    newParents.Add(new KeyValuePair<int,long>(node.LevelId, node.NodeId));
                    GetTableRowsRecursive(node.Children, newParents);
                }

            }

        }
        public void BuildTable()
        {
            GetMaxDepth();
            dt = new DataTable();
            for (int i = 1; i <= maxDepth; i++)
            {
                string columnName = string.Format("Level {0} Node ID", i.ToString());
                dt.Columns.Add(columnName, typeof(int));
            }
            GetTableRowsRecursive(nodes, null);
        }
        public void PrintTable()
        {
            string line = string.Join("   ",dt.Columns.Cast<DataColumn>().Select(x => string.Format("{0,-15}",x.ColumnName)));
            Console.WriteLine(line);
            foreach (DataRow row in dt.AsEnumerable())
            {
                line = string.Join("   ", row.ItemArray.Select(x => string.Format("{0,-15}", x)));
                Console.WriteLine(line);
            }
        }

    }
}

输出

在此处输入图像描述


推荐阅读