我正在学习scala,我想执行以下任务: 我有以下文本文件作为输入:
10 location String
10 age String
10 Salary String
15 job String
10 Name String
15 Status String
我应该写的代码可以描述如下: 如果一行以15开头,则第二个字段必须替换为以10开头的第一个前一行的第二个字段。 因此输出应如下所示:
10 location String
10 age String
10 Salary String
15 Salray String
10 Name String
15 Name String
答案 0 :(得分:0)
def replace1510 (lines: List[String], last10: String) : List [String] =
if (lines.isEmpty) Nil else {
val row = lines.head.split ("[ \t]+")
row(0).toInt match {
case 10 => lines.head :: replace1510 (lines.tail, row(1))
case 15 => (row(0) + " " + last10 + "\t" + row (2)) :: replace1510 (lines.tail, last10)
case _ => lines.head :: replace1510 (lines.tail, last10)
}
}
scala> replace1510 (lines.toList, "").mkString ("\n")
res180: String =
10 location String
10 age String
10 Salary String
15 Salary String
10 Name String
15 Name String
根据您的需要,您的输出最终可能需要一些化妆品。
我将行拆分为空白和制表符,并期望第一个值可以作为Int进行解析,匹配它。
要么(10)更新last10值,要么用记忆的last10值替换中间字段,或者只是将行交给。
lines.tail
是列表的其余部分,第一行除外,row(1)
是“location”。 我的数据准备:
scala> val data = """10 location String
| 10 age String
| 10 Salary String
| 15 job String
| 10 Name String
| 15 Status String"""
data: String =
10 location String
10 age String
10 Salary String
15 job String
10 Name String
15 Status String
scala> val lines = data.split ("\n")
lines: Array[String] = Array(10 location String, 10 age String, "10 Salary String ", 15 job String, 10 Name String, 15 Status String)
答案 1 :(得分:0)
除了使用其他人建议的递归方法之外,另一种处理文本的方法是使用foldLeft
遍历拆分子串列表来执行处理逻辑。
请注意,tuple
(List [Array [String]],String)用作foldLeft
的累加器,以迭代方式转换数组列表以及继承字符串元素有条件的替代。
val textArr = scala.io.Source.
fromFile("/path/to/textfile").
getLines.map(_.split("\\s+")).
toList
val id1 = "10"
val id2 = "15"
val outputList = textArr.foldLeft( (List[Array[String]](), textArr.head(1)) ){
(acc, x) => x(0) match {
case `id1` => ( x :: acc._1, x(1) )
case `id2` => ( x.updated(1, acc._2) :: acc._1, acc._2 )
case _ => ( x :: acc._1, acc._2 )
}
}._1.reverse.
map(_.mkString(" "))
// outputList: List[String] = List(10 location String, 10 age String, ...)
outputList.foreach(println)
// 10 location String
// 10 age String
// 10 Salary String
// 15 Salary String
// 10 Name String
// 15 Name String
如果您不熟悉方法foldLeft
,则它具有以下签名。有关详细信息,请参阅此Scala API doc
def foldLeft[B](z: B)(op: (B, A) ⇒ B): B
[UPDATE]
如果您的输入数据是字符串列表,则可以创建textArr
,如下所示,并应用上述foldLeft
转换:
val stringList = Seq(
"10 location String",
"10 age String",
"10 Salary String",
"15 job String",
"10 Name String",
"15 Status String"
)
val textArr = stringList.map(_.split("\\s+"))