使用 linq 获取路径的所有父级
我想在没有显式循环的情况下获取路径的所有父级,以便我可以完全消除此方法。
private static IEnumerable<string> GetParentPaths(string path)
{
while (Path.GetDirectoryName(path) != Path.GetPathRoot(path))
{
path = Path.GetDirectoryName(path);
yield return path;
}
}
如何使用 LINQ 干净地完成此操作?
给定
c:\a\b\c
应该返回以下内容(顺序无关紧要)
c:\a
c:\a\b
更新:
@Tomas Petricek的回答让我Jon Skeet 的生成器实现 我最终得到以下结果:
path.Generate(Path.GetDirectoryName)
.Skip(1) // the original
.TakeWhile(p => p != Path.GetPathRoot(p))
使用
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(current);
}
}
}
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(current);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Enumerable
提供的标准方法不够强大,无法轻松编码while
循环。如果您想通过调用某些通用方法来重写代码,您还需要实现一些通用方法。如果添加Generate
方法,您的问题可以得到很好的解决:Generate
方法的想法是,它不断重复调用提供的 lambda 函数来生成新状态(在此casepath
) 直到返回null
。该方法会生成所有生成的值。您可以这样编写Generate
:该方法本质上只是隐藏了原始方法中使用的可重用模式。特定行为作为函数传递,因此您可以将该方法用于许多不同的目的。
The standard methods provided by
Enumerable
aren't powerful enough to encodewhile
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 aGenerate
method:The idea of the
Generate
method is that it keeps calling the provided lambda function repeatedly to generate new state (in this casepath
) until it returnsnull
. The method yields all generated values as it goes. You can writeGenerate
like this: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.