首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在自引用linq中获得针对高度父节点的极值叶节点

如何在自引用linq中获得针对高度父节点的极值叶节点
EN

Stack Overflow用户
提问于 2017-11-03 14:37:44
回答 2查看 74关注 0票数 3

我有了数据结构

代码语言:javascript
运行
复制
-Emp1 - Emp1_1 - Emp1_1_1
               - Emp1_1_2
      - Emp1_2 - Emp1_2_1
               - Emp1_2_2
-Emp2 - Emp2_1 - Emp2_1_1
               - Emp2_1_2
      - Emp2_2 - Emp2_2_1
               - Emp2_2_2

我想要一个字典,它拥有极端的叶节点作为关键字和它的最高父作为值。操作:

(Emp1_1_1,Emp1) (Emp1_1_2,Emp1) (Emp1_2_1,Emp1) (Emp1_2_2,Emp1) (Emp2_1_1,Emp2) (Emp2_1_2,Emp2) (Emp2_2_1,Emp2) (Emp2_2_2,Emp2)

代码语言:javascript
运行
复制
(Emp1_1_1, Emp1)
(Emp1_1_2, Emp1) 
(Emp1_2_1, Emp1)
(Emp1_2_2, Emp1)
(Emp2_1_1, Emp2)
(Emp2_1_2, Emp2)
(Emp2_2_1, Emp2)
(Emp2_2_2, Emp2)

下面是c#代码

代码语言:javascript
运行
复制
public class Program
    {
        public static void Main()
        {
            var program = new Program();
            var empList = program.GetData();
           //Some linq which return the expected dictionary.
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int parentEmployee { get; set; }
            public List<Employee> childList { get; set; }
        }

        List<Employee> GetData()
        {
            var empList = new List<Employee>();

            var emp1 = new Employee() { Id = 1, Name = "Emp1_Name", childList = new List<Employee>() };
            var emp1_1 = new Employee() { Id = 2, Name = "Emp1_1_Name", parentEmployee = emp1.Id, childList = new List<Employee>() };
            var emp1_2 = new Employee() { Id = 3, Name = "Emp1_2_Name", parentEmployee = emp1.Id, childList = new List<Employee>() };
            emp1.childList.Add(emp1_1);
            emp1.childList.Add(emp1_2);
            var emp1_1_1 = new Employee() { Id = 4, Name = "Emp1_1_1_Name", parentEmployee = emp1_1.Id };
            var emp1_1_2 = new Employee() { Id = 5, Name = "Emp1_1_2_Name", parentEmployee = emp1_1.Id };
            emp1_1.childList.Add(emp1_1_1);
            emp1_1.childList.Add(emp1_1_2);
            var emp1_2_1 = new Employee() { Id = 6, Name = "Emp1_2_1_Name", parentEmployee = emp1_2.Id };
            var emp1_2_2 = new Employee() { Id = 7, Name = "Emp1_2_2_Name", parentEmployee = emp1_2.Id };
            emp1_2.childList.Add(emp1_2_1);
            emp1_2.childList.Add(emp1_2_2);



            var emp2 = new Employee() { Id = 1, Name = "emp2_Name", childList = new List<Employee>() };
            var emp2_1 = new Employee() { Id = 2, Name = "emp2_1_Name", parentEmployee = emp2.Id, childList = new List<Employee>() };
            var emp2_2 = new Employee() { Id = 3, Name = "emp2_2_Name", parentEmployee = emp2.Id, childList = new List<Employee>() };
            emp2.childList.Add(emp2_1);
            emp2.childList.Add(emp2_2);
            var emp2_1_1 = new Employee() { Id = 4, Name = "emp2_1_1_Name", parentEmployee = emp2_1.Id };
            var emp2_1_2 = new Employee() { Id = 5, Name = "emp2_1_2_Name", parentEmployee = emp2_1.Id };
            emp2_1.childList.Add(emp2_1_1);
            emp2_1.childList.Add(emp2_1_2);
            var emp2_2_1 = new Employee() { Id = 6, Name = "emp2_2_1_Name", parentEmployee = emp2_2.Id };
            var emp2_2_2 = new Employee() { Id = 7, Name = "emp2_2_2_Name", parentEmployee = emp2_2.Id };
            emp2_2.childList.Add(emp2_2_1);
            emp2_2.childList.Add(emp2_2_2);

            empList.Add(emp1);
            empList.Add(emp2);
            return empList;
        }
    }

我尝试了一些解决方案,比如在linq中调用私有自引用函数,但它适用于一父一子关系。

EN

回答 2

Stack Overflow用户

发布于 2017-11-03 16:03:24

如果可以使用递归函数:

代码语言:javascript
运行
复制
        Func<IEnumerable<Employee>, IEnumerable<Employee>> flatten = null;
        flatten = (IEnumerable<Employee> employees) => 
            employees.SelectMany(c => c.childList != null ? flatten(c.childList) : Enumerable.Empty<Employee>()).Concat(employees);

        var dict = (
            from topNode in empList
                    from node in flatten(topNode.childList)
                    where node.childList == null || node.childList.Count == 0
                    select new KeyValuePair<string, string>(node.Name, topNode.Name)
            ).ToDictionary(kv => kv.Key, kv => kv.Value);


        foreach(var keyValuePair in dict)
        {
            Console.WriteLine($"Key={keyValuePair.Key}, Value={keyValuePair.Value}");
        }

这将输出以下内容:

代码语言:javascript
运行
复制
Key=Emp1_1_1_Name, Value=Emp1_Name
Key=Emp1_1_2_Name, Value=Emp1_Name
Key=Emp1_2_1_Name, Value=Emp1_Name
Key=Emp1_2_2_Name, Value=Emp1_Name
Key=emp2_1_1_Name, Value=emp2_Name
Key=emp2_1_2_Name, Value=emp2_Name
Key=emp2_2_1_Name, Value=emp2_Name
Key=emp2_2_2_Name, Value=emp2_Name
票数 1
EN

Stack Overflow用户

发布于 2017-11-03 18:11:57

尝尝这个

代码语言:javascript
运行
复制
public static void Main()
{
    var program = new Program();
    var empList = program.GetData();

    Func<IEnumerable<Employee>, Employee, Dictionary<Employee, Employee>> TreeToDict = null;
    TreeToDict = (employees, topParent) => 
    employees.SelectMany(e => 
                         {
                             if(e.childList != null)
                             {
                                 return TreeToDict(e.childList, topParent == null ? e : topParent);
                             }
                             else
                             {
                                 Dictionary<Employee, Employee> dict = new Dictionary<Employee, Employee>();
                                 dict.Add(e, topParent == null ? e : topParent);
                                 return dict;
                             }

                         }).ToDictionary(x => x.Key, x => x.Value);

    foreach(var emp in TreeToDict (empList, null))
    {
        Console.WriteLine("key : {0}, value {1}", emp.Key.Name, emp.Value.Name);
    }
}

结果

代码语言:javascript
运行
复制
key : Emp1_1_1_Name, value Emp1_Name
key : Emp1_1_2_Name, value Emp1_Name
key : Emp1_2_1_Name, value Emp1_Name
key : Emp1_2_2_Name, value Emp1_Name
key : emp2_1_1_Name, value emp2_Name
key : emp2_1_2_Name, value emp2_Name
key : emp2_2_1_Name, value emp2_Name
key : emp2_2_2_Name, value emp2_Name
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47089835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档