从文件创建Vector [Vector [Char]]

时间:2012-11-10 16:38:20

标签: scala

我是新手,试图读取文件并创建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) (_ +: _)

文件永远不会很大,因此可扩展性不是问题。上面的代码似乎有效,但我觉得它在谷仓周围都是如此。有没有更简单,更直接的方法来做到这一点?

4 个答案:

答案 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

wrapStringscala.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")对象。