2

I'm pretty sure there is a simple answer to this, but it's killing me why I cant figure this out. I'm trying to populate a treeview based on a 5-character string.

public List<string> lst = new List<string>();

lst.Add("10000");
lst.Add("11000");
lst.Add("11100");
lst.Add("12000");
lst.Add("12100");
lst.Add("20000");
lst.Add("21000");
lst.Add("22000");

I'm trying to get the above in this type of tree

hierarchy

Again, I'm sure it is old hat to many experienced C# developers, but I just can't figure out a simple recursive or linq solution.

Mohammad Dehghan
  • 17,853
  • 3
  • 55
  • 72
Brad
  • 25
  • 6
  • What are you using for you treeview WinForms or WPF? Please take a look at this link: http://social.msdn.microsoft.com/Forums/en/winforms/thread/dae1c72a-dd28-4232-9aa4-5b38705c0a97 – Ramón García-Pérez Feb 23 '13 at 06:40
  • i think i might have misrepresented the problem. in the above i'm adding the values to the list, but in reality these string values have already been assigned. I have gotten as far as to create a list of strings just do not know how to decompose them into a tree structure. – Brad Feb 23 '13 at 07:04
  • 1
    Are you looking for a structure that is similar to a [trie](http://en.wikipedia.org/wiki/Trie)? – Devendra D. Chavan Feb 23 '13 at 07:20
  • Take a look at [How to create a trie in c#](http://stackoverflow.com/a/6416341/529196) and [Basic trie data structure implementation (C#)](http://counterhelix.com/2011/08/16/basic-trie-data-structure-implementation/). You can then map the nodes to the tree view after creating the trie. – Devendra D. Chavan Feb 23 '13 at 07:39
  • not hard to believe have never heard of that data structure, but the trie data structure appears it could be extended to easily support the treeview – Brad Feb 23 '13 at 07:42
  • by the way thanks Devendra, I will work through what you gave me pretty sure it will work better than what i was even planned. thanks again! – Brad Feb 23 '13 at 07:54

1 Answers1

1

This recursive method should do it:

static TreeNode[] GetNodes(IEnumerable<string> items, string prefix = "")
{
    int preLen = prefix.Length;

    // items that match the current prefix and have a nonzero character right after
    // the prefix
    var candidates = items.Where(i => i.Length > preLen &&
                                      i[preLen] != '0' &&
                                      i.StartsWith(prefix));

    // create nodes from candidates that have a 0 two characters after the prefix.
    // their child nodes are recursively generated from the candidate list
    return candidates.Where(i => i.Length > preLen + 1 && i[preLen + 1] == '0')
                     .Select(i => 
                          new TreeNode(i, GetNodes(candidates, prefix + i[preLen])))
                     .ToArray();
}

You can just invoke it like this:

treeView.Nodes.AddRange(GetNodes(lst));
JLRishe
  • 99,490
  • 19
  • 131
  • 169