Skip to content

Instantly share code, notes, and snippets.

@ivanbuhov
Created May 4, 2014 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivanbuhov/5d7a1a0bfdbf993c7137 to your computer and use it in GitHub Desktop.
Save ivanbuhov/5d7a1a0bfdbf993c7137 to your computer and use it in GitHub Desktop.
Reduce File Path
using System;
using System.Collections.Generic;
using System.Linq;
namespace ReduceFilePath
{
class ReduceFilePath
{
public const string CurrentFolderToken = ".";
public const string ParentFolderToken = "..";
public const char TokensDelimiter = '/';
static void Main()
{
while (true)
{
Console.Write("Enter a path to reduce: ");
string path = Console.ReadLine();
string reducedPath = ReducePath(path);
Console.Write("Reduced path: ");
Console.WriteLine(reducedPath);
}
}
public static string ReducePath(string path)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
bool hasLastDash = (path[path.Length - 1] == '/');
string[] pathTokens = path.Split(new char[] { TokensDelimiter }, StringSplitOptions.RemoveEmptyEntries);
Stack<string> tokensStack = new Stack<string>();
int rootOffset = 0; // the depth level relative to the root
foreach (string token in pathTokens)
{
if (token == ParentFolderToken)
{
// If we are in a root descendant - remove the last folder
if (rootOffset > 0)
{
tokensStack.Pop();
}
rootOffset--;
}
else if (token != CurrentFolderToken)
{
tokensStack.Push(token);
rootOffset++;
}
}
// Handles cases like "/../" where the last dash has meaning
if (hasLastDash && rootOffset == -1)
{
rootOffset++;
}
// If the result directory is above the root
if (rootOffset < 0)
{
throw new Exception("Invalid path. There is no folders above the root.");
}
return "/" + String.Join("/", tokensStack.Reverse());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment