如何深入List并获取其parentIds

时间:2018-01-24 16:14:35

标签: c#

我正面临一个问题,我必须深入查看列表,直到找到所需的contentId。一旦匹配了contentId,我需要得到它的ParentIds。我能够获取contentId但不能获取其ParentId。

目前我正在使用递归来获取子节点的ParentIds。但未能取得理想的结果。 任何人都可以让它运行,或提供正确的代码来解决这个问题。我试图获取childnode及其parentIds。我需要获取parentIds,然后想要插入List。

我能够深入了解循环但不知道如何以及何时将parentIds存储到列表中。

在此代码中,我试图获取contentId" 5"的父母。

class Program
        {
            static void Main(string[] args)
            {
                Program obj = new Program();
                var data = obj.GetAllChildCats();
                foreach (var item in data)
                {
                    Console.WriteLine(item);
                }
                Console.ReadLine();
            }

            public List<int> GetAllChildCats()
            {
                var ret = getdata();
                var data = GetAllChildCats(4, ret.contentObjects, 0);
                return data;
            }

            List<int> parentIdsList1 = new List<int>();

            private List<int> GetAllChildCats(int id, ContentObjects data, int Parentid)
            {
                if (!string.IsNullOrEmpty(data.ContentObjectId.ToString()))
                {
                    parentIdsList1.Add(Parentid);
                    if (data.ContentObjectId == id)
                    {
                        return parentIdsList1;
                    }
                    else
                    {
                        if (data.ChildContentObjects != null)
                        {
                            foreach (ContentObjects cat in data.ChildContentObjects)
                            {
                                GetAllChildCats(id, cat, data.ContentObjectId);
                            }
                        }
                    }
                }
                return parentIdsList1;
            }

            public Heirarchy getdata()
            {
                Heirarchy ret = new Heirarchy()
                {
                    _id = 11,
                    contentObjects = new ContentObjects()
                    {
                        ContentObjectId = 1,
                        NodeId = 34,
                        ChildContentObjects = new List<ContentObjects>()
                        {
                            new ContentObjects() {
                                ContentObjectId=2,
                                NodeId=34,
                                ChildContentObjects= new List<ContentObjects>()
                                {
                                    new ContentObjects() {
                                    ContentObjectId=3,
                                    NodeId=34,
                                    ChildContentObjects= null
                                    }
                                }
                            },
                            new ContentObjects() {
                                ContentObjectId=4,
                                NodeId=34,
                                ChildContentObjects= new List<ContentObjects>()
                                {
                                    new ContentObjects() {
                                    ContentObjectId=5,
                                    NodeId=34,
                                    ChildContentObjects= null
                                    }
                                }
                            },
                        }
                    },
                    HierarchyId = 2
                };
                return ret;
            }
        }

        public class Heirarchy
        {
            public int _id { get; set; }
            public ContentObjects contentObjects { get; set; }
            public int HierarchyId { get; set; }   
        }

        public class ContentObjects
        {
            public int ContentObjectId { get; set; }
            public int NodeId { get; set; }
            public List<ContentObjects> ChildContentObjects { get; set; }
        }

1 个答案:

答案 0 :(得分:1)

  

在这段代码中,我试图让contentId的父母为“5”。

这可以通过简单的深度优先搜索来解决。我们只需要在深入挖掘树之前检查孩子的ID ,这样我们仍然可以返回父参考:

static void Main(string[] args)
{
    Program obj = new Program();

    var parents = obj.GetParentsOf(5, obj.getdata().contentObjects);

    Console.WriteLine(parents.Count()); // yields 1
    Console.WriteLine(parents.First().ContentObjectId); // yields 4
    Console.ReadLine();
}

private IEnumerable<ContentObjects> GetParentsOf(int id, ContentObjects root)
{
    if (root.ChildContentObjects != null)
    {
        foreach (ContentObjects c in root.ChildContentObjects)
        {
            // If a direct child has the requested ID, we are a parent.
            if (c.ContentObjectId == id)
            {
                yield return root;
            }

            // Recurse deeper down.
            foreach (ContentObjects found in GetParentsOf(id, c))
            {
                yield return found;
            }
        }
    }
}

另一方面,如果“父母”是指树中的完整路径,我们需要按如下方式修改方法。我们再次进行了递归深度优先搜索,但是当从成功的递归步骤返回时,我们将自己的id插入到路径中:

static void Main(string[] args)
{
    Program obj = new Program();

    var path = obj.GetPathTo(5, obj.getdata().contentObjects);

    // prints 1, 4
    foreach (ContentObjects o in path)
    {
        Console.WriteLine(o.ContentObjectId);
    }
    Console.ReadLine();
}

// returns null if id could not be found
private IEnumerable<ContentObjects> GetPathTo(int id, ContentObjects root)
{
    if (root.ChildContentObjects != null)
    {
        foreach (ContentObjects c in root.ChildContentObjects)
        {
            if (c.ContentObjectId == id)
            {
                // If a direct child has the requested ID, we are the first parent.
                return new[] { root };
            }
            else
            {
                // Recurse deeper down.
                var found = GetPathTo(id, c);
                if (found != null)
                {
                    // We found something deeper down. Since we are part of the
                    // path, append own id.
                    return new[] { root }.Concat(found);
                }
            }
        }
    }

    return null;
}