Matriz a CSV en Scala

Writing an MxN matrix ( M rows, N columns ) to a CSV file:

My first attempt, using map, works, but creates N references to the stringbuffer. It also writes an unnecessary comma at the end of each row.

def matrix2csv(matrix:List[List[Double]], filename: String ) = {
  val pw = new PrintWriter( filename )
  val COMMA = ","

  matrix.map( row => {
    val sbuf = new StringBuffer  
    row.map( elt => sbuf.append( elt ).append( COMMA ))
    pw.println(sbuf)
  })
  pw.flush
  pw.close
}

My second attempt, using reduce, also works but looks clunky:

def matrix2csv(matrix:List[List[Double]], filename: String ) = {
  val pw = new PrintWriter( filename )
  val COMMA = ","

  matrix.map( row => {
    val sbuf = new StringBuffer  
    val last = row.reduce( (a,b)=> {
      sbuf.append(a).append(COMMA)
      b
    })
    sbuf.append(last)
    pw.println(sbuf)
  })
  pw.flush
  pw.close
}

Any suggestions on a more concise and idiomatic approach ? Thanks.

preguntado el 08 de noviembre de 11 a las 16:11

How do you get the 2nd attempt to compile? In sbuf.append(b), no hay b en alcance. -

2 Respuestas

You can obtain the string representation easily:

val csvString = matrix.map{ _.mkString(", ") }.mkString("\n")

Then you just need to dump it in a file.

Pay attention to end-lines (here "\n" ), they vary according to the platform.

respondido 08 nov., 11:20

Thanks, that's very concise & idiomatic. - kr

Idiomatically, you're misusing map by using it to perform side-effecting operations. You should use foreach para esto en su lugar.

This is what it could look like if you used a foreach and replaced your StringBuffer boilerplate with a call to the mkString método:

def matrix2csv(matrix:List[List[Double]], filename: String) {
  val pw = new PrintWriter(filename)
  val COMMA = ","
  matrix.foreach { row => pw.println(row mkString COMMA) }
  pw.flush
  pw.close
}

Tenga en cuenta que mkString utiliza una StringBuilder (a non-thread-safe StringBuffer, which is fine here).

respondido 08 nov., 11:20

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.