我是新手,试图读取文件并创建Vector [Vector [Char]]。文件的每一行都应该生成不同的向量。
以下是我的想法:
val empty: Vector[Vector[Char]] = Vector()
lazy val lines: List[String] = Source.fromFile("test.txt").getLines.toList
lazy val vecList: List[Vector[Char]] = lines.map(str => Vector(str: _*))
lazy val vector: Vector[Vector[Char]] = vecList.foldRight(empty) (_ +: _)
文件永远不会很大,因此可扩展性不是问题。上面的代码似乎有效,但我觉得它在谷仓周围都是如此。有没有更简单,更直接的方法来做到这一点?
答案 0 :(得分:5)
以下是使用Scala 2.10的解决方案:
source.getLines.to[Vector].map(_.to[Vector])
答案 1 :(得分:1)
正如我在上面的评论中所指出的,在需要能够在恒定时间内获取特定索引处的元素的情况下,使用IndexedSeq
更为惯用。 IndexedSeq
的当前默认实现是Vector
,因此如果您编写以下内容:
val xs = IndexedSeq(1, 2, 3)
你实际上会在幕后获得Vector[Int]
,但这只是一个实现细节,因为它被静态输入为IndexedSeq[Int]
。如果将来引入新的,更高性能的默认实现,您将从免费更改中受益。
使用IndexedSeq
还可以非常简洁地编写此操作,而无需依赖Scala 2.10的新to
方法。假设我们有一个源s
我们在其他地方打开和关闭,这就是您所需要的:
val lines: IndexedSeq[IndexedSeq[Char]] = s.getLines.map(wrapString).toIndexedSeq
wrapString
是scala.Predef
提供的一种方法,支持将字符串视为字符序列。
答案 2 :(得分:1)
import scala.io.Source
2.9或更早:
Vector() ++ Source.fromFile("test.txt").getLines.map(Vector() ++ _)
2.10及之后:
Source.fromFile("test.txt").getLines.map(_.to[Vector]).to[Vector]
(首先在迭代器上映射,这样你就不必再创建两次向量。)
答案 3 :(得分:0)
稍微改进,避免foldLeft()
:
Vector(Source.fromFile("test.txt").getLines.toSeq: _*) map {l => Vector(l: _*)}
但请记住,您实际上必须关闭Source.fromFile("test.txt")
对象。