2016-06-27 34 views
-1

我不明白为什么我的输出文件正在失去其顺序。使用csv阅读器库无法保持csv列顺序(tototoshi)

我正在上传带有标题的csv文件(key1 | key2 | key3)。然后,我使用CsvDataReader来遍历头文件(scala.Iterator[Map[String, String]])。我映射此迭代器,因为我想为csv文件添加值,我为输出创建一个新文件,但输出的顺序与原始文件不同...首先,它是:

key1 key2 key3和映射后,我希望看到key1 key2 key3 key4

但结果却是相反:

key3 key1 key4 key2

这是为什么?

这是我的代码:

val csvFile = new File(Crypto.decryptAES(request.fileId)) 
    if (csvFile.exists()) { 

     val csvDataReader = new CsvDataReader(csvFile) 

     val resultLines = csvDataReader.iteratorWithHeaders.map(row => { 
     row ++ Map("key4" -> "val4", "key5" -> "val5") 

     }).toList 

     val headerOfFile = resultLines.head.keys.toList 

     val outputFile = File.createTempFile("output-", ".csv") 

     val csvDataWriter = new CsvDataWriter(outputFile,true) 
     csvDataWriter.writeHeaders(headerOfFile) 

     resultLines foreach {csvDataWriter.write(_,headerOfFile)} 
     csvDataReader.close() 
     csvDataWriter.close() 
+0

知道你的课程来自哪里会很酷......如果它们包含可能相关的错误,你不这么认为吗? – Dici

+0

@Dici哪个类?我分享了一段包含bug的代码,并且所有的东西都直接转发到csv阅读器库文件夹 – Joe

回答

0

默认地图Scala中使用Map时返回的scala.collection.immutable.HashMap,这是无序的。 row ++ Map(...)也返回scala.collection.immutable.HashMap,因此它无序。

看看这个API,除了重复调用readNext之外别无选择。

def appendList[T](list: List[T], toAppend: Seq[T]) = new ListBuffer[T]() ++= list ++= toAppend 

val csvFile = new File(Crypto.decryptAES(request.fileId)) 
if (csvFile.exists()) { 
    val csvDataReader = new CsvDataReader(csvFile) 

    val headers = csvDataReader.readNext().getOrElse(Nil) 
    val newHeaders = appendList(headers, List("key4", "key5")) 

    val outputFile = File.createTempFile("output-", ".csv") 

    val csvDataWriter = new CsvDataWriter(new BufferedWriter(new FileWriter(outputFile))) 

    csvDataReader.iterator.foreach {csvDataWriter.writeRow(appendList(_, List("value4", "value5"))} 

    csvDataReader.close() 
    csvDataWriter.close() 

这个答案是基于磁带库(https://github.com/tototoshi/scala-csv,提交715e726),这显然不是你所使用的最新版本。

+0

如何使用LinkedHashMap实现它,假设它返回有序映射? resultLines返回'scala.List [Map [String,String]]' – Joe

+0

我正在查看代码,没有任何东西可以保证这个方法的顺序。 – Dici

+0

@Joe更新了我的答案 – Dici