Here is a very simple implementation (assuming the nodes are in the correct order) that can be expanded in several ways.
public interface IRow<out T> { string TextNode { get; } T Value { get; } } public class TreeNode<T> { private struct NodeDescriptor { public int Level { get; } public int ParentIndex { get; } public NodeDescriptor(IRow<T> row) { var split = row.TextNode.Split(new [] {"/"}, StringSplitOptions.RemoveEmptyEntries); Level = split.Length; ParentIndex = split.Length > 1 ? int.Parse(split[split.Length - 2]) - 1 : 0; } } public T Value { get; } public List<TreeNode<T>> Descendants { get; } private TreeNode(T value) { Value = value; Descendants = new List<TreeNode<T>>(); } public static TreeNode<T> Parse(IReadOnlyList<IRow<T>> rows) { if (rows.Count == 0) return null; var result = new TreeNode<T>(rows[0].Value); FillParents(new[] {result}, rows, 1, 1); return result; } private static void FillParents(IList<TreeNode<T>> parents, IReadOnlyList<IRow<T>> rows, int index, int currentLevel) { var result = new List<TreeNode<T>>(); for (int i = index; i < rows.Count; i++) { var descriptor = new NodeDescriptor(rows[i]); if (descriptor.Level != currentLevel) { FillParents(result, rows, i, descriptor.Level); return; } var treeNode = new TreeNode<T>(rows[i].Value); parents[descriptor.ParentIndex].Descendants.Add(treeNode); result.Add(treeNode); } } }
Sample Usage:
public class Row : IRow<string> { public string TextNode { get; } public string Value { get; } public Row(string textNode, string userName) { TextNode = textNode; Value = userName; } } class Program { static void Main(string[] args) { IRow<string>[] rows = { new Row("/", "Ahmed"), new Row("/1/", "Saeed"), new Row("/2/", "Amjid"), new Row("/1/1/", "Noura"), new Row("/2/1/", "Noura01"), new Row("/2/2/", "Reem01"), new Row("/1/1/1", "Under_noura") }; var tree = TreeNode<string>.Parse(rows); PrintTree(tree); } private static void PrintTree<T>(TreeNode<T> tree, int level = 0) { string prefix = new string('-', level*2); Console.WriteLine("{0}{1}", prefix, tree.Value); foreach (var node in tree.Descendants) { PrintTree(node, level + 1); } } }
source share