2010-04-28 3 views
3

Я хочу объединить два относительных пути в C#.Есть ли простой способ объединить два относительных пути в C#?

Например:

string path1 = "/System/Configuration/Panels/Alpha"; 
string path2 = "Panels/Alpha/Data"; 

Я хочу вернуть

string result = "/System/Configuration/Panels/Alpha/Data"; 

я могу осуществить это путем разделения второго массива и сравнить его в цикле, но мне было интересно, если есть что-то подобное до Path.Combine или если это может быть выполнено с помощью регулярных выражений или Linq?

Благодаря

+5

Что случилось с Path.Combine? –

+0

@ Kyle Alons: @loannis хочет, чтобы метод Combine распознавал общие сегменты пути и «сливал» их соответственно. –

+3

Путь.Combine вернется «/ System/Configuration/Panels/Alpha/Data/Panels/Alpha/Data» – Ioannis

ответ

4

При условии, что эти две строки всегда в том же формате, как в вашем примере, это должно работать:

string path1 = "/System/Configuration/Panels/Alpha"; 
string path2 = "Panels/Alpha/Data"; 

var x = path1.Split('/'); 
var y = path2.Split('/'); 

string result = Enumerable.Range(0, x.Count()) 

          .Where(i => x.Skip(i) 
             .SequenceEqual(y.Take(x.Skip(i) 
                   .Count()))) 

          .Select(i => string.Join("/", x.Take(i) 
                 .Concat(y))) 

          .LastOrDefault(); 

// result == "/System/Configuration/Panels/Alpha/Data" 

Для path1 = "/System/a/b/a/b" и path2 = "a/b/a/b/c" результат "/System/a/b/a/b/a/b/c". Вы можете изменить LastOrDefault до FirstOrDefault вместо "/System/a/b/a/b/c".


Обратите внимание, что этот алгоритм по существу создает все возможные комбинации двух путей и не особенно эффективен.

+0

+1 ... Молодцы! –

+0

Спасибо, что это очень элегантный код. не хотел использовать для. :) – Ioannis

+1

Предостережение заключается в том, что вы должны * предположить *, что «Панели/Альфа» - это те же папки, что и «/ System/Configuration/* Panels/Alpha *» –

4

Я думаю, что это требует априорного знания, что некоторые папки одинаковы, то вы не можете безопасно вывести из всего пути (при условии, что это не абсолютное).

Вам нужно будет написать собственную пользовательскую логику, чтобы выполнить объединение этих путей.

+0

+1: без известной точки привязки, то же имя не обязательно означает ту же папку в иерархии. –

+0

Предполагая, что часть значения path1 всегда известна (например, «/ System/Configuration/....», возможно. – Ioannis

+0

@loannis, но это потребует, чтобы вы * знали *, что существует определенное количество перекрываются и что ваша структура папок не содержит других путей, которые имеют похожие имена. –

1

Попробуйте это ...

var p1 = path1.Split('/'); 
var p2 = path2.Split('/'); 

result = p1.Union(p1); 

Он использует System.Linq, и может быть легко упакована в метод расширения.

Конечно, он предполагает что-то о значениях path1 и path2.

+0

Хотя мое решение, вероятно, тоже не идеально, это не так много для других случаев. Например, если 'path1 ="/System/Panels/Configuration/Panels/Alpha "и' path2 = "Панели/Альфа/Данные", результатом будет ''/System/Panels/Configuration/Alpha/Data "' , – dtb

+0

Согласен ... хотя действительно, его невозможно обеспечить «наилучшим образом» решение без какого-либо дополнительного контекста. – pblasucci

0

Path.GetFullPath (Path.Combine (путь1, путь2))

GetFullPath будет объединить и упростить полученный путь.

EDIT: Ничего, что работает только для абсолютных путей ...