1

Given:

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

I want to be able to take a string and a list of files of replacements and replace bracketed items. So if I have:

replLines("Hello",["cat"]) and cat contains ello,i!, I want to get back Hi!

I tried:

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)
}

I think the syntax is close, but not quite there. What have I done wrong?

1
  • 1
    For every condition <cond> and conclusion <conc>, the statement 'IF <cond> AND ("cat" contains "ello,i!"), THEN <conc>' is logically valid. So, for example, the statement "if I have: replLines("Hello",["cat"]) and "cat" contains "ello,i!", every yellow rubber duck can program." is valid. But it is not very helpful, because from false premises, everything follows. Can you somehow convert your code into an MCVE that does not depend on external files? Right now, the question is unclear. Commented Apr 2, 2018 at 16:03

1 Answer 1

2

What you're looking for is most likely this (note the foldLeft[String] instead of 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 generalizes the fold initial argument too much, and considers it a Serializable, not a String. foldLeft (and foldRight, if you prefer to start your replacements from the end) allows you to explicitly specify the type you fold on

EDIT: In fact, you don't even need a recursive pattern matching at all, as you can map your replacements directly to the list:

def replLines2(inpQ: String, y: List[String]): String =
  y.flatMap(toKVMap).foldLeft[String](inpQ) {
    case (str, (k, v)) => str.replace(s"[$k]", v)
  }
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.