递归父子关系C#

时间:2017-01-18 05:19:49

标签: c# recursion hierarchy

我正在尝试从.csv文件构建Hierarchy,它由ID(功能位置),描述&组成。父ID(SupFunctLoc)都是字符串。我已将数据提取到列表中。 代码&数据样本供参考。

 Functional Loc.    Description SupFunctLoc.
 70003  ABC AS002
 70C2   ABC 70003
 70C2.01    ABC 70C2
 70C2.01.02 ABC 70C2.01
 70C2.01.02.10  ABC 70C2.01.02
 70C2.01.02.10-BG010    ABC 70C2.01.02.10

示例代码:

static void Main(string[] args)
    {
        List<Input> inputList = new List<Input>();
        var yourData = File.ReadAllLines(locate)
               .Skip(1)
               .Select(x => x.Split(','))
               .Select(x => new Input()
               {
                   FunctionalLocation = x[0],
                   Description = x[1],
                   SuppFunctionalLocation = x[2],

               });
        //try 3

        //try 2

        var outputList = yourData
            .Where(i => i.SuppFunctionalLocation!= null) // Just get the parents
            .Select(i => new Input()
            {
                Description = i.Description,
                SuppFunctionalLocation = i.SuppFunctionalLocation,
                Children = inputList
                    .Where(x => x.FunctionalLocation.ToString() == i.SuppFunctionalLocation.ToString())
                    .Select(x => new Input()
                    {
                        Description = x.Description,
                        SuppFunctionalLocation = x.SuppFunctionalLocation,
                        FunctionalLocation = x.FunctionalLocation,
                    }).ToList()
                }).ToList();


        foreach (var output in outputList)
        {
            Console.WriteLine(output.Description);
            output.Children.ForEach(c => Console.WriteLine($"\t {c.Description}"));
        }
}

输入的类别定义

 class Input
    {
        public string FunctionalLocation { get; set; }
        public string Description { get; set; }
        public string SuppFunctionalLocation { get; set; }
        public List<Input> Children { get; set; }
    }

请帮助解决在这种情况下可以做的事情。非常感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

一旦您阅读了集合中的所有项目,就会与

建立父关系
foreach ( var parent in inputlist )
{
    parent.Children = inputlist
        .Where( child => child.SuppFunctionalLocation == parent.FunctionalLocation )
        .ToList();
}

要仅获取根元素,您必须查找没有父元素的所有项目

var outputlist = inputlist
    .Where( child => !inputlist.Any( parent => parent.FunctionalLocation == child.SuppFunctionalLocation ) )
    .ToList();

答案 1 :(得分:0)

使用现有父键的项目构建层次结构相对容易。我从你的样本中抽取了一点,但它基本相同。

要放入层次结构的项目

public class MyItem
{
    public string Id { get; set; }
    public string Description { get; set; }
    public string ParentId { get; set; }
    // to be filled
    public IList<MyItem> Children { get; set; }
}

构建子列表的代码。

// assumption: MyItem elements have all properties set except the children collection
ICollection<MyItem> items = GetMyItems();

var parentRelation = items.ToLookup(x => x.ParentId);
foreach (var item in items)
{
    item.Children = parentRelation[item.Id].ToList();
}

答案 2 :(得分:0)

试试这个:

var source = @"Functional Loc.    Description SupFunctLoc.
70003  ABC AS002
70C2   ABC 70003
70C2.01    ABC 70C2
70C2.01.02 ABC 70C2.01
70C2.01.02.10  ABC 70C2.01.02
70C2.01.02.10-BG010    ABC 70C2.01.02.10";

var lines =
    source
        .Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
        .Select(x => x.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));

var results =
    lines
        .Skip(1)
        .Select(x => new Input()
        {
            FunctionalLocation = x[0],
            Description = x[1],
            SuppFunctionalLocation = x[2],
        });

var lookup = results.ToLookup(x => x.SuppFunctionalLocation);

Func<string, List<Input>> build = null;
build = SuppFunctionalLocation =>
    lookup[SuppFunctionalLocation]
        .Select(x => new Input()
        {
            FunctionalLocation = x.FunctionalLocation,
            Description = x.Description,
            SuppFunctionalLocation = x.SuppFunctionalLocation,
            Children = build(x.FunctionalLocation),
        })
        .ToList();

List<Input> tree = build("AS002");