在Scala中将文件名拆分为绝对路径

7

考虑到字符串

val path = "/what/an/awesome/path" 

我该如何使用Scala为路径中的每个目录创建绝对路径列表?结果应为:


List(/what, /what/an, /what/an/awesome, /what/an/awesome/path)

优秀的、功能强大的解决方案将获得额外加分。

我对所有高质量答案感到非常惊讶。我希望我能接受不止一个答案,但由于这是不可能的,我将接受第一个正确的答案。感谢您的支持。 - mre
5个回答

15
val path = "/what/an/awesome/path"
val file = new java.io.File(path)
val prefixes = Iterator.iterate(file)(_.getParentFile).takeWhile(_ != null).toList.reverse

我以前从未见过这种方法。请问我是否理解正确?每次迭代后,由.getParentFile返回的对象都会成为“新”的file吗? - Geo
不错。+1。这会将根目录作为第一个元素返回,对吗? - huynhjl
3
在这种情况下,添加一个.drop(1)就可以轻松解决了 :-) - leedm777
1
@Tempus 是的,它是 Iterator.iterate(startingValue)(functionToDeriveNext)。各种集合类型的 companions 上有许多类似的工厂方法。例如,Iterator.continually 也很有趣。http://www.scala-lang.org/api/rc/scala/collection/Iterator$.html - David Winslow
请注意,如果路径不是来自文件系统的根目录,您可能需要在其上使用.getCanonicalPath - Rex Kerr

8
val path = "/what/an/awesome/path"

scala> path.tail.split("/").scanLeft(""){_ + "/" + _}.tail.toList
res1: List[java.lang.String] = List(/what, /what/an, /what/an/awesome, /what/an/awesome/path)

4

使用Jesse Eichar的新Scala IO库(版本0.2.0),似乎可以这样做:

val path  = Path("/what/an/awesome/path")
val paths = (path :: path.parents).reverse

你可能希望将结果列表中的Path对象转换为字符串,但是保留它们作为Path对象可能更安全、更有用。

据我所知,这个库正在考虑纳入Scala发行版。


2
path.drop(1).split("/").foldLeft(List.empty[String])((list, string) => ((list.headOption.getOrElse("") + "/" + string) :: list)).reverse.toList

可能有更简洁的方法使用scanLeft,但我无法理解它


2
大概是这样的 path.split("/").drop(1).scanLeft("")((s,elem) => s + "/" + elem).drop(1) - huynhjl

2

高级正则表达式方法:

val R = "(/.*)/".r
(path + '/').inits.collect{case R(x) => x}.toList

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接