Scala - 列表上的标准递归模式匹配

时间:2018-04-02 15:42:57

标签: scala

假设:

def readLines(x: String): List[String] = Source.fromFile(x).getLines.toList
def toKVMap(fName : String): Map[String,String] =
  readLines(fName).map(x => x.split(',')).map { case Array(x, y) => (x, y) }.toMap

我希望能够获取一个字符串和一个替换文件列表,并替换括号内的项目。如果我有:

replLines("Hello",["cat"])cat包含ello,i!,我想回来Hi!

我试过了:

def replLines(inpQ : String, y : List[String]): String = y match { 
  case Nil => inpQ
  case x::xs => replLines(toKVMap(x).fold(inpQ) {
    case ((str: String), ((k: String), (v: String))) =>
      str.replace("[" + k + "]", v).toString
  }, xs)
}

我认为语法很接近,但并不完全存在。我做错了什么?

1 个答案:

答案 0 :(得分:2)

您最有可能寻找的内容(请注意foldLeft[String]代替fold

def replLines(inpQ: String, y: List[String]): String = y match {
    case Nil => inpQ
    case x :: xs => replLines(toKVMap(x).foldLeft[String](inpQ) {
        case ((str: String), ((k: String), (v: String))) =>
            str.replace("[" + k + "]", v)
    }, xs)
}

fold过多地​​概括了fold初始参数,并认为它是Serializable,而不是StringfoldLeft(和foldRight,如果您希望从最后开始替换,则允许您明确指定您折叠的类型

编辑:事实上,您根本不需要递归模式匹配,因为您可以将替换直接映射到列表:

def replLines2(inpQ: String, y: List[String]): String =
  y.flatMap(toKVMap).foldLeft[String](inpQ) {
    case (str, (k, v)) => str.replace(s"[$k]", v)
  }