Prashant Prashant - 1 month ago 10
C# Question

How to create hierarchical structure with list of path?

I'm playing with the Dropbox's Delta API, when I call delta method I get a list of path's that changed since last call.

/photos
/public
/photos/sample album
/photos/sample album/boston city flow.jpg
/photos/sample album/pensive parakeet.jpg
/photos/sample album/costa rican frog.jpg
/getting started.pdf
/photos/how to use the photos folder.txt
/public/how to use the public folder.txt
/ies eai.pptx
/documents
/documents/windows phone toolkit in depth 2nd edition.pdf
/prashant
/prashant/iphone indexed list.bmml
/photos/flower.jpg
/photos/trs
/photo.jpg
/hello1
/hello1/new


I had a hard time creating hierarchical (in below mentioned class) structure out of it by manipulating the string, could anyone suggest a way/idea I can achieve it.

public class DeltaItem
{

private List<DeltaItem> _items;
public string Path { get; set; }
public bool IsDir { get; set; }

public List<DeltaItem> Items
{
get
{
return _items ?? (_items = new List<DeltaItem>());
}
}
}

Answer

It's a pretty simple parse operation. First, I'd define the class like so:

public class Node
{
    private readonly IDictionary<string, Node> _nodes = 
        new Dictionary<string, Node>();

    public string Path { get; set; }
}

From there it's a matter of:

  1. Parsing the path (using \ as the delimiter).
  2. Traversing down the tree, adding new nodes if necessary.

You can wrap the above in a single method Add:

public void AddPath(string path)
{
   char[] charSeparators = new char[] {'\\'};

   // Parse into a sequence of parts.
   string[] parts = path.Split(charSeparators, 
       StringSplitOptions.RemoveEmptyEntries);

   // The current node.  Start with this.
   Node current = this;

   // Iterate through the parts.
   foreach (string part in parts)
   {
       // The child node.
       Node child;

       // Does the part exist in the current node?  If
       // not, then add.
       if (!current._nodes.TryGetValue(part, out child))
       {
           // Add the child.
           child = new Node {
               Path = part
           };

           // Add to the dictionary.
           current._nodes[part] = child;
       }

       // Set the current to the child.
       current = child;
   }
}

This will give you the hierarchy you need. You can expose operations that work on the dictionary which will allow you to traverse it, but this is how you'd populate the general structure you'd be working with.

Note that you'd start off with a singular node that has no Path and then iterate through your list above and call AddPath on every item in the list above.