最后一个答案之后:Recursive method to convert flat collection to hierarchal collection?
我想使用相同的CreateTree方法,但要使用层次结构之外的其他对象:ItemNode:
public class ItemNode
{
public string Id { get; set; }
public Item Item { get; set; }
public ICollection<ItemNode> Children { get; set; }
}
和Item的定义:
public class Item
{
public string ID { get; set; }
public string Name { get; set; }
public int Level { get; set; }
public string ParentId { get; set; }
}
这里是带有ItemNode的CreateTree方法:
static List<ItemNode> CreateTreeItems(IEnumerable<ItemNode> nodes)
{
Dictionary<string,ItemNode> idToNode = nodes.ToDictionary(n => n.Id, n => n);
List<ItemNode> roots = new List<ItemNode>();
ItemNode root = null;
foreach (var n in nodes)
{
if (n.Item.ParentId == null)
{
if (root != null)
{
roots.Add(root);
}
root = n;
continue;
}
ItemNode parent = idToNode[n.Item.ParentId];
//if (!idToNode.TryGetValue(n.Item.ParentId, out parent))
//{
// //Parent doesn't exist, orphaned entry
//}
parent?.Children.Add(n);
// RETURNS FALSE WHEREAS IN THE ORIGINAL METHOD IT RETURNS TRUE
var test = Object.ReferenceEquals(parent, root);
Debug.WriteLine(test);
}
if (root == null)
{
//There was no root element
}
roots.Add(root);
return roots;
}
它不起作用,因为父级和根级没有引用同一对象(而在原始方法中,它引用了)。我想这与我已经向ItemNode类添加Item属性的事实有关。但是我不知道如何解决。
谢谢!
答案 0 :(得分:1)
为什么期望根节点和父节点引用相等?每个根节点可能是一个父节点,但并非每个父节点都是一个根节点。
在某些情况下,引用是相等的,但这在很大程度上取决于nodes
集合的排序顺序。实际上,当根节点放置在第一级子节点之前时,您会看到引用相等的情况。
我想您的问题出在其他地方,例如,如果Nodes
集合根本没有根节点,则可能无法解决问题。
这里是示例,请在此处https://dotnetfiddle.net/4r52xP
using System;
using System.Collections.Generic;
using System.Linq;
public class Hierarchy
{
public Hierarchy(string iD, string name, int level, string parentID, string topParent)
{
ID = iD;
Name = name;
Level = level;
ParentID = parentID;
Children = new HashSet<Hierarchy>();
}
public string ID { get; set; }
public string Name{ get; set; }
public int Level { get; set; }
public string ParentID { get; set; }
public ICollection<Hierarchy> Children { get; set; }
}
public class Program
{
static Hierarchy CreateTree(IEnumerable<Hierarchy> Nodes)
{
var idToNode = Nodes.ToDictionary(n => n.ID, n => n);
Hierarchy root = null;
foreach (var n in Nodes)
{
if (n.ParentID == null)
{
if (root != null)
{
//there are multiple roots in the data
}
root = n;
continue;
}
Hierarchy parent = null;
if (!idToNode.TryGetValue(n.ParentID, out parent))
{
//Parent doesn't exist, orphaned entry
}
parent.Children.Add(n);
Console.WriteLine("ReferenceEquals: {0}", Object.ReferenceEquals(parent, root));
}
if (root == null)
{
//There was no root element
}
return root;
}
public static void Main()
{
Console.WriteLine("Test #1");
List<Hierarchy> l = new List<Hierarchy>();
l.Add(new Hierarchy("295152","name1",1,null, null)); // <-root node at the top of the list
l.Add(new Hierarchy("12345","child1",2,"295152", null));
l.Add(new Hierarchy("54321","child2",2,"295152", null));
l.Add(new Hierarchy("44444","child1a",3,"12345", null));
l.Add(new Hierarchy("33333","child1b",3,"12345", null));
l.Add(new Hierarchy("22222","child2a",3,"54321", null));
l.Add(new Hierarchy("22221","child2b",3,"54321", null));
l.Add(new Hierarchy("22002","child2c",3,"54321", null));
l.Add(new Hierarchy("20001","child2a2",4,"22222", null));
l.Add(new Hierarchy("20101","child2b2",4,"22222", null));
CreateTree(l);
Console.WriteLine("\nTest #2");
l = new List<Hierarchy>();
l.Add(new Hierarchy("12345","child1",2,"295152", null));
l.Add(new Hierarchy("54321","child2",2,"295152", null));
l.Add(new Hierarchy("44444","child1a",3,"12345", null));
l.Add(new Hierarchy("33333","child1b",3,"12345", null));
l.Add(new Hierarchy("22222","child2a",3,"54321", null));
l.Add(new Hierarchy("22221","child2b",3,"54321", null));
l.Add(new Hierarchy("22002","child2c",3,"54321", null));
l.Add(new Hierarchy("20001","child2a2",4,"22222", null));
l.Add(new Hierarchy("20101","child2b2",4,"22222", null));
l.Add(new Hierarchy("295152","name1",1,null, null)); // <-root node at the bottom of the list
CreateTree(l);
}
}