开发者

get all parents of a path with linq

I'd like to get all parents of a path without an explicit loop so that I can eliminate this method entirely.

private static IEnumerable<string> GetParentPaths(string path)
{
    while (Path.GetDirectoryName(path) != Path.GetPathRoot(path))
    {
        path = Path.GetDirectoryName(path);
        yield return path;
    }
}

How could this be done cleanly with LINQ?

given

c:\a\b\c

should return the following (order doesn't matter)

c:\a
c:\a\b

update:

@Tomas Petricek's answer led me to Jon Skeet's Generator implementation and I ended up with the following:

path.Generate(Path.GetDirectoryName)
    .Skip(1) // the original
    .TakeWhile(p => p != Path.GetPathRoot(p))

using

public static class TExtensions
{
    public static IEnumerable<T> Generate<T>(this T initial, Func<T, T> next) 
    {
        var current = initial;
        while (true)
        {
            yield return current;
            current = next(开发者_如何学Gocurrent);
        }
    }
}


The standard methods provided by Enumerable aren't powerful enough to encode while loop easily. If you want to rewrite the code by calling some general purpose method, you'll need to implement some general purpose method too. Your problem could be nicely solved if you added a Generate method:

EnumerableEx.Generate(path, path => 
  Path.GetDirectoryName(path) != Path.GetPathRoot(path) 
  ? Path.GetDirectoryName(path) : null);

The idea of the Generate method is that it keeps calling the provided lambda function repeatedly to generate new state (in this case path) until it returns null. The method yields all generated values as it goes. You can write Generate like this:

static IEnumerable<T> Generate<T>(T initial, Func<T, T> next) {
  T current = initial;
  while(true) {
    current = next(current);
    if (current == default(T)) return;
    yield return current;
  }
}

The method essentially just hides a reusable pattern that was used in your original method. The specific behavior is passed as a function, so you could use the method for many different purposes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜