patterncsharpMinor
Basic folder tree with a list of strings
Viewed 0 times
withbasicfolderliststringstree
Problem
I am building up a basic folder tree with a list of strings in the form /root/node/node/node. Here is the basic algorithm I am using currently to build this collection and fill in my
Once I have the final list built, I then add the nodes to the tree (for simplification, I have removed the calls to end update and begin update of the tree that contains the root node):
```
void FillTreeNodes(TreeNode root)
{
var rootText = root.Text;
var rootTextLength = rootText.Length;
var nodeStrings = BuildFinalList();
foreach(var nodeString in nodeStrings)
{
var roots = nodeString.Split(new char[] { '/' }
TreeGridView:// This method gets the list of folders and leaves, then trims out any folder paths
// that are already encompassed in a larger folder path, the idea is that it causes
// less work when adding the actual tree nodes (I may be wrong in this assumption)
List BuildFinalList()
{
// This list is a collection of root folder paths and leaf folder names
// i.e. pair("/root/node/node", "node"), pair("/root/node", "node)
List> folders = GetListOfFolders();
var paths = new List();
foreach(var folder in folders)
{
var leaf = folder.Value;
var root = folder.Key;
paths.Add(string.Concat(root, "/", leaf);
}
paths.Sort(_INVERSE_LENGTH_COMPARE); // this sorts the list longest to shortest
// Iterate the computed paths from longest to shortest, if a path is not
// encompassed by an existing path in the final list, add it to the
// final list, otherwise just move to the next path
var finalList = new List();
foreach(var path in paths)
{
bool found = false;
foreach(var item in finalList)
{
if (item.StartsWith(path, StringComparison.Ordinal))
{
found = true;
break;
}
}
if (!found)
{
finalList.Add(path);
}
}
return finalList;
}Once I have the final list built, I then add the nodes to the tree (for simplification, I have removed the calls to end update and begin update of the tree that contains the root node):
```
void FillTreeNodes(TreeNode root)
{
var rootText = root.Text;
var rootTextLength = rootText.Length;
var nodeStrings = BuildFinalList();
foreach(var nodeString in nodeStrings)
{
var roots = nodeString.Split(new char[] { '/' }
Solution
One improvement that comes to mind is:
Finding out whether a condition is met for any item in a collection is a common enough problem that LINQ has a method for that:
Which is both shorter and simpler.
bool found = false;
foreach(var item in finalList)
{
if (item.StartsWith(path, StringComparison.Ordinal))
{
found = true;
break;
}
}Finding out whether a condition is met for any item in a collection is a common enough problem that LINQ has a method for that:
Enumerable.Any. Using that the above code can be written as just:bool found = finalList.Any(item =>
item.StartsWith(path,StringComparison.Ordinal);Which is both shorter and simpler.
Code Snippets
bool found = false;
foreach(var item in finalList)
{
if (item.StartsWith(path, StringComparison.Ordinal))
{
found = true;
break;
}
}bool found = finalList.Any(item =>
item.StartsWith(path,StringComparison.Ordinal);Context
StackExchange Code Review Q#707, answer score: 6
Revisions (0)
No revisions yet.