Матрица в CSV в Скала - PullRequest
       12

Матрица в CSV в Скала

5 голосов
/ 08 ноября 2011

Запись матрицы MxN (M строк, N столбцов) в файл CSV:

Моя первая попытка с использованием карты работает, но создает N ссылок на строковый буфер. В конце каждой строки также записывается ненужная запятая.

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
}

Моя вторая попытка, использующая уменьшение, также работает, но выглядит неуклюже:

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
}

Есть предложения о более кратком и идиоматическом подходе? Спасибо.

Ответы [ 2 ]

8 голосов
/ 08 ноября 2011

Вы можете легко получить строковое представление:

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

Тогда вам просто нужно поместить его в файл.

Обратите внимание на конечные строки (здесь "\ n")они различаются в зависимости от платформы.

5 голосов
/ 08 ноября 2011

Идиоматически, вы неправильно используете map, используя его для выполнения побочных действий.Вместо этого вы должны использовать foreach.

Вот как это могло бы выглядеть, если бы вы использовали foreach и заменили шаблон StringBuffer на вызов метода mkString:

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
}

Обратите внимание, что mkString использует StringBuilder (без потока StringBuffer, что здесь хорошо).

...