Reputation: 1373
I'd like to modify a source string which is looking like
"one.two.three"
and transfer it into a string with slashes to use it as a folder string which has the following structure:
"one\one.two\one.two.three"
Do you know more elegant ways to realize this, than my solution below? I'm not very satisfied with my for-loops.
var folder = "one.two.three";
var folderParts = folder.Split('.');
var newFolder = new StringBuilder();
for (int i = 0; i < folderParts.Length; i++)
{
for (int j = 0; j < i; j++)
{
if (j == 0)
{
newFolder.Append("\\");
}
newFolder.Append($"{folderParts[j]}.");
}
newFolder.Append(folderParts[i]);
}
Upvotes: 6
Views: 276
Reputation: 42225
You can do this quite tersely with Regex
var newFolder = Regex.Replace(folder, @"\.", @"\$`.");
This matches on each period. Each time it finds a period, it inserts a backslash and then the entire input string before the match ($`
). We have to add the period in again at the end.
So, steps are (< and > indicate text inserted by the substitution at that step):
one<\one>.two.three
one\one.two<\one.two>.three
one\one.two\one.two.three
For bonus points, use Path.DirectorySeparatorChar
for cross-platform correctness.
var newFolder = Regex.Replace(folder, @"\.", $"{Path.DirectorySeparatorChar}$`.")
Here's another linqy way:
var a = "";
var newFolder = Path.Combine(folder.Split('.')
.Select(x => a += (a == "" ? "" : ".") + x).ToArray());
Upvotes: 9
Reputation: 6002
Instead of splitting the string first, I find it more elegant to start with what you have and reduce it:
var folder = "one.two.three";
var newFolder = string.Empty;
for (var f = folder; f.Any(); f = f.Remove(Math.Max(f.LastIndexOf('.'), 0)))
newFolder = Path.Combine(f, newFolder);
Console.WriteLine(newFolder);
Output:
one\one.two\one.two.three
Upvotes: 3
Reputation: 14007
You can go forward-only in one loop like this:
var folder = "one.two.three";
var newFolder = new StringBuilder();
int index = -1;
while (index + 1 < folder.Length) {
index = folder.IndexOf('.', index + 1);
if (index < 0) {
newFolder.Append(folder);
break;
}
else {
newFolder.Append(folder, 0, index);
newFolder.Append(Path.DirectorySeparatorChar);
}
}
You can try it out here.
Upvotes: 3
Reputation: 186668
You can try Linq:
string folder = "one.two.three";
string[] parts = folder.Split('.');
string result = Path.Combine(Enumerable
.Range(1, parts.Length)
.Select(i => string.Join(".", parts.Take(i)))
.ToArray());
Console.Write(newFolder);
Outcome:
one\one.two\one.two.three
Upvotes: 8