scala - 如何概括 'Seq[String] => Seq[Int]' 和 'Iterator[String] => Iterator[Int]' 的实现以进行文件处理?
问题描述
假设我有一个函数Seq[String] => Seq[Int]
,例如def len(as: Seq[String]): Int = as.map(_.length)
。现在我想将此函数应用于文本文件,例如将所有文件行转换为数字。
我读了一个文本文件,因为scala.io.Source.fromFile("/tmp/xxx.txt").getLines
它返回一个迭代器。
我可以使用toList
或to(LazyList)
将迭代器“转换”为,Seq
但随后我将整个文件读入内存。
所以我需要再写一个函数Iterator[String] => Iterator[Int]
,其实就是复制的Seq[String] => Seq[Int]
. 这是正确的吗 ?避免重复代码的最佳方法是什么?
解决方案
如果你有一个任意函数Seq[String] => Seq[Int]
,那么
我使用 toList 或 to(LazyList) 将迭代器“转换”为 Seq,但在这两种情况下,我都读取了内存中的整个文件。
是您能做的最好的,因为该函数可以从查看 结尾Seq[String]
或其长度等开始。
而且 Scala 不允许您查看函数的“内部”并找出“它是map(something)
,我可以对迭代器做同样的事情map
”(宏有一些警告,但在这里并不是很有用)。
所以我需要再写一个函数
Iterator[String] => Iterator[Int]
,其实就是复制的Seq[String] => Seq[Int]
. 这是正确的吗 ?避免重复代码的最佳方法是什么?
如果您控制函数的定义,则可以使用更高种类的类型来定义适用于这两种情况的函数。例如在 Scala 2.13 中
def len[C[A] <: IterableOnceOps[A, C, C[A]]](as: C[String]): C[Int] = as.map(_.length)
val x: Seq[Int] = len(Seq("a", "b"))
val y: Iterator[Int] = len(Iterator("a", "b"))
推荐阅读
- java - 如何使模板引擎同时处理来自数据库和文件系统的 thymeleaf 页面
- node.js - 未设置 cookie
- unity3d - 代码中的请求插页式广告功能放在哪里?
- php - mysqli_fetch_array 时的 PHP SQL 查询
- sublimetext - SublimeLinter ESLint 找不到插件
- amazon-web-services - 将存储桶同步到本地目录,不重复
- scala - 即使未使用原子 compareAndSet 参数,也会对其进行评估
- javascript - 返回上一页后图像未隐藏
- bash - 使用 sed 进行内联搜索和替换
- jquery - 根据链接参数自定义onclick确认消息