NET 通用方法:把扁平数据转换为树形数据结构【表格】

1.表格文件:节点打横成一行,根节点需要关联附属信息【Remark1 / Remark2】

  2.demo

        [Theory]
        [InlineData(@"C:\Working\TestTreeNode.xlsx")]
        public void Run(string path)
        {
            // 节点后端 属性名集合
            var nodeNameList = new List<string> { "Node1", "Node2", "Node3" };
            // 最末级节点-附属信息 属性名集合
            var propertyNameList = new List<string> { "Remark1", "Remark2" };
            var modelList = NpoiHelper.ConvertList<TestNodeDto>(path);
            var dic = new List<string>();

            foreach (var itemModel in modelList)
            {
                var itemKey = string.Empty;
                var itemLastNodeFieldName = itemModel.GetLastNodeFieldName();
                for (int i = 0; i < nodeNameList.Count; i++)
                {
                    // 获取 节点后端 属性名
                    var itemNodeName = nodeNameList[i];
                    // 获取 节点后端 属性值
                    var itemNodeValue = itemModel[itemNodeName];
                    if (itemNodeValue.IsNullOrWhiteSpace()) break;

                    var propertyList = new List<string>();
                    // 如果是最后一个节点,则获取附属信息
                    if (itemLastNodeFieldName.Equals(itemNodeName))
                    {
                        foreach (var itemPropertyName in propertyNameList)
                        {
                            propertyList.Add($"{itemPropertyName}:{itemModel[itemPropertyName]}");
                        }
                    }
                    itemKey += itemNodeValue;
                    // 过滤重复节点
                    if (!dic.Contains(itemKey))
                    {
                        dic.Add(itemKey);
                        var prefix = Enumerable.Repeat("\t", i).Join("");
                        _testOutputHelper.WriteLine($"{prefix}{itemNodeName}:{itemNodeValue}\t{propertyList.Join("\t")}");
                    }
                }
            }
            _testOutputHelper.WriteLine("Run");
        }

3.TestNodeDto

    /// <summary>
    /// 测试树形节点 实体
    /// </summary>
    public class TestNodeDto
    {
        public string Code { get; set; }

        [DisplayName("Node1")]
        public string Node1 { get; set; }

        [DisplayName("Node2")]
        public string Node2 { get; set; }

        [DisplayName("Node3")]
        public string Node3 { get; set; }

        [DisplayName("Remark1")]
        public string Remark1 { get; set; }

        [DisplayName("Remark2")]
        public string Remark2 { get; set; }

        /// <summary>
        /// 获取最后一个节点字段名
        /// </summary>
        /// <returns></returns>
        public string GetLastNodeFieldName()
        {
            // 从最后一个子节点往根节点判断,只要任意节点有值,则为 最后一个节点
            if (!Node3.IsNullOrWhiteSpace()) return nameof(Node3);
            if (!Node2.IsNullOrWhiteSpace()) return nameof(Node2);
            if (!Node1.IsNullOrWhiteSpace()) return nameof(Node1);
            return string.Empty;
        }

        public string this[string fieldName]
        {
            get
            {
                switch (fieldName)
                {
                    case nameof(Node1): return Node1;
                    case nameof(Node2): return Node2;
                    case nameof(Node3): return Node3;
                    case nameof(Remark1): return Remark1;
                    case nameof(Remark2): return Remark2;
                    default:
                        return string.Empty;
                }
            }
        }
    }

4.输出结果

Node1:Lv0    
    Node2:Lv0-1    
        Node3:Lv0-1-1    Remark1:附属信息1:Lv0-1-1    Remark2:附属信息2:Lv0-1-1
        Node3:Lv0-1-2    Remark1:附属信息1:Lv0-1-2    Remark2:附属信息2:Lv0-1-2
        Node3:Lv0-1-3    Remark1:附属信息1:Lv0-1-3    Remark2:附属信息2:Lv0-1-3
        Node3:Lv0-1-4    Remark1:附属信息1:Lv0-1-4    Remark2:附属信息2:Lv0-1-4
        Node3:Lv0-1-5    Remark1:附属信息1:Lv0-1-5    Remark2:附属信息2:Lv0-1-5
    Node2:Lv0-2    
        Node3:Lv0-2-1    Remark1:附属信息1:Lv0-2-1    Remark2:附属信息2:Lv0-2-1
        Node3:Lv0-2-2    Remark1:附属信息1:Lv0-2-2    Remark2:附属信息2:Lv0-2-2
        Node3:Lv0-2-3    Remark1:附属信息1:Lv0-2-3    Remark2:附属信息2:Lv0-2-3
    Node2:Lv0-3    Remark1:附属信息1:Lv0-3    Remark2:附属信息2:Lv0-3
    Node2:Lv0-5    Remark1:附属信息1:Lv0-5    Remark2:附属信息2:Lv0-5
Node1:Lv1    
    Node2:Lv1-1    
        Node3:Lv1-1-1    Remark1:附属信息1:Lv1-1-1    Remark2:附属信息2:Lv1-1-1
    Node2:Lv1-2    Remark1:附属信息1:Lv1-2    Remark2:附属信息2:Lv1-2
    Node2:Lv1-3    Remark1:附属信息1:Lv1-3    Remark2:附属信息2:Lv1-3

 

posted @ 2021-11-02 17:37  Robot-Blog  阅读(99)  评论(0编辑  收藏  举报