Search code examples
listscalainputscala-2.9mutability

Scala, read file manipulate each line, insert each line into list


I'm reading a file line by line, replacing substring "replace" with substring "replacment". Once string manipulation is complete I want to insert each line into a list.

def importFile(replaceString:String, filePath:String, replacement:String)= {
  val fileLineList = io.Source.fromURL(getClass.getResource(filePath))
    .getLines
    .foreach(line => {line.replace(replaceString,replacement)}.toList)
  print(fileLineList)
}

When I call the function all that is returned is:

()

Any Ideas, ?


Solution

  • If you want to return your list of strings, you could do one of the two things:

    def importFile(replaceString:String, filePath:String, replacement:String)= {
      io.Source.fromURL(getClass.getResource(filePath))
        .getLines
        .map(_.replace(replaceString,replacement))
    }
    

    or

    def importFile(replaceString:String, filePath:String, replacement:String)= {
      val fileLineList = io.Source.fromURL(getClass.getResource(filePath))
        .getLines
        .map(_.replace(replaceString,replacement))
      print(fileLineList)
      fileLineList
    }
    

    The first variant will not print anything, but will return the result (all lines from file after replacement). The second variant will print the replaced version and then return it.

    In general, in Scala the result of the function is its last statement. Keep in mind that the statement like:

    val myValue = 5
    

    will not return anything (its type is Unit), whereas

    myValue
    

    (if it was defined before) will specify the result as whatever is stored in myValue.

    the .map(_.replace(replaceString,replacement)) part should transform each of the original lines , using replace. _ is syntactic sugar for

    .map(x => x.replace(replaceString, replacement))
    

    which can be also written as

    .map{x => x.replace(replaceString, replacement)}
    

    but in this simple case it's not necessary. Curlies would make sense if you had a mapping function that consisted of several statements, for example:

    .map{x => 
        val derivedValue = someMethod(x)
        derivedValue.replace(replaceString, replacement)
     }
    

    Most important part is the difference between .map and .foreach:

    .map transforms the original sequence into the new sequence (according to the mapping function) and returns this sequence (in your case, list of strings).

    .foreach iterates over the given sequence and performs the specified operations over every entry in the sequence, but it does not return anything - it's return type is Unit.

    (Check Scaladoc for List for more information about these and other functions: http://www.scala-lang.org/api/2.10.3/index.html#scala.collection.immutable.List )