I am trying to search hierarchical data based on the advice provided in this question How to search Hierarchical Data with Linq . However, I am stuck.
var NodeTypes = new NodeType[] {
new NodeType{
NodeTypeDescription = "First Level",
Item = new CodeType(){ CodeValue = "01" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "First Child Level 0101",
Item = new CodeType(){ CodeValue = "0101" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 1234, ModelTitle = "Target-1234" },
Node = null
}
}
},
new NodeType{
NodeTypeDescription = "First Child Level 0102",
Item = new CodeType(){ CodeValue = "0102" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 2345, ModelTitle = "Target-2345" },
Node = null
}
}
}
}
},
new NodeType{
NodeTypeDescription = "Second Level",
Item = new CodeType(){ CodeValue = "02" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Second Child Level 0201",
Item = new CodeType(){ CodeValue = "0201" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Second Child Level 020101",
Item = new CodeType(){ CodeValue = "020101" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 2345, ModelTitle = "Target-2345" },
Node = null
}
}
}
}
},
new NodeType{
NodeTypeDescription = "Second Child Level 0202",
Item = new CodeType(){ CodeValue = "0202" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 3456, ModelTitle = "Target-3456" },
Node = null
}
}
}
}
}
};
I have placed the sample code here.
public static class Extensions
{
public static IEnumerable<T> Flatten<T>(this T source, Func<T, IEnumerable<T>> selector)
{
return selector(source).SelectMany(c => Flatten(c, selector))
.Concat(new[] { source });
}
}
public class ModelType
{
public string ModelTitle;
public long ModelId;
}
public class CodeType
{
public string CodeValue;
}
public class NodeType
{
public string NodeTypeDescription { get; set; }
public object Item { get; set; }
public NodeType[] Node { get; set; }
}
public class Program
{
public static void Main()
{
var NodeTypes = new NodeType[] {
new NodeType{
NodeTypeDescription = "First Level",
Item = new CodeType(){ CodeValue = "01" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "First Child Level 0101",
Item = new CodeType(){ CodeValue = "0101" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 1234, ModelTitle = "Target-1234" },
Node = null
}
}
},
new NodeType{
NodeTypeDescription = "First Child Level 0102",
Item = new CodeType(){ CodeValue = "0102" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 2345, ModelTitle = "Target-2345" },
Node = null
}
}
}
}
},
new NodeType{
NodeTypeDescription = "Second Level",
Item = new CodeType(){ CodeValue = "02" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Second Child Level 0201",
Item = new CodeType(){ CodeValue = "0201" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Second Child Level 020101",
Item = new CodeType(){ CodeValue = "020101" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 2345, ModelTitle = "Target-2345" },
Node = null
}
}
}
}
},
new NodeType{
NodeTypeDescription = "Second Child Level 0202",
Item = new CodeType(){ CodeValue = "0202" },
Node = new NodeType[]{
new NodeType{
NodeTypeDescription = "Target Level Description",
Item = new ModelType(){ ModelId = 3456, ModelTitle = "Target-3456" },
Node = null
}
}
}
}
}
};
var result = NodeTypes[0].Flatten(x => x.Node).Where(y => ((ModelType)(y.Item)).ModelId == 2345);
}
}
I don't think this is right
var result = NodeTypes[0].Flatten(x => x.Node).Where(y => ((ModelType)(y.Item)).ModelId == 2345);
as I want to search all nodes and the target node could be at any depth,
Another question ...
After flattening the hierarchy, how can we also get the details from the parent or sibling. Say, I want to extract the codeValue from its parent's sibling Item node.
var result2 = DepthFirst<NodeType>(NodeTypes, n => n.Node).ToList();
var result1 = result2.Where(n => n.Item.GetType() == typeof(ModelType) && ((ModelType)n.Item).ModelId == 2345).ToList();