using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var items = new[]
{
new Item{ Parent = null, Child = "A", Name = "Alpha" },
new Item{ Parent = "A", Child = "B", Name = "Bravo" },
new Item{ Parent = "A", Child = "C", Name = "Charlie" },
new Item{ Parent = "B", Child = "E", Name = "Echo" },
new Item{ Parent = "B", Child = "F", Name = "Foxtrot" },
new Item{ Parent = "C", Child = "W", Name = "Whisky" },
new Item{ Parent = "C", Child = "H", Name = "Hotel" },
new Item{ Parent = "W", Child = "V", Name = "Victor" },
};
var root = new TreeNode<Item>(items.Single(i => i.Parent == null));
AddDescendants(items, root);
Console.WriteLine("# Tree flat-style:");
root.Traverse(item => Console.WriteLine("Node name: " + item.Value.Name));
Console.WriteLine();
Console.WriteLine("# Tree indent-style:");
root.Traverse(node =>
{
var depth = 0;
var ancestor = node.Parent;
while (ancestor != null)
{
depth++;
ancestor = ancestor.Parent;
}
Console.WriteLine(new string(' ', depth * 2) + node.Value.Name);
});
Console.ReadKey();
}
private static void AddDescendants(IReadOnlyCollection<Item> items, TreeNode<Item> node)
{
var children = node.AddChildren(items.Where(i => i.Parent == node.Value.Child).ToArray());
foreach (var child in children)
{
AddDescendants(items, child);
}
}
}
public class Item
{
public string Parent { get; set; }
public string Child { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
}
public class TreeNode<T>
{
private readonly T _value;
private readonly List<TreeNode<T>> _children = new List<TreeNode<T>>();
public TreeNode(T value)
{
_value = value;
}
public TreeNode<T> this[int i]
{
get { return _children[i]; }
}
public TreeNode<T> Parent { get; private set; }
public T Value { get { return _value; } }
public ReadOnlyCollection<TreeNode<T>> Children
{
get { return _children.AsReadOnly(); }
}
public TreeNode<T> AddChild(T value)
{
var node = new TreeNode<T>(value) { Parent = this };
_children.Add(node);
return node;
}
public TreeNode<T>[] AddChildren(params T[] values)
{
return values.Select(AddChild).ToArray();
}
public bool RemoveChild(TreeNode<T> node)
{
return _children.Remove(node);
}
public void Traverse(Action<TreeNode<T>> action)
{
action(this);
foreach (var child in _children)
child.Traverse(action);
}
public IEnumerable<T> Flatten()
{
return new[] { Value }.Concat(_children.SelectMany(x => x.Flatten()));
}
}
}