如何将矩阵复制到列数组

时间:2015-12-16 14:35:18

标签: scala csv

我试图将矩阵的列复制到数组中,我也希望将此矩阵公开。

继承我的代码:

Spinner spinner = (Spinner) findViewById(R.id.spinner);
spinner.setSelection(5); // Not displaying 5th item, Yes! there are more than 5 items.
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        spinner.setSelection(position);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
        spinner.setSelection(5);
    }
});

我希望val years = Array.ofDim[String](1000, 1) val bufferedSource = io.Source.fromFile("Top_1_000_Songs_To_Hear_Before_You_Die.csv") val i=0; //println("THEME, TITLE, ARTIST, YEAR, SPOTIFY_URL") for (line <- bufferedSource.getLines) { val cols = line.split(",").map(_.trim) years(i)=cols(3)(i) } 成为一个全局矩阵并将第3列复制到cols,因为我得到cols的方法我不知道如何定义它

3 个答案:

答案 0 :(得分:1)

您的尝试中出现了三个不同的问题

  1. 此数据集的正则表达式将失败。我建议你把它改成:

    val regex = ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))"

  2. 这将捕获用双引号包裹的块,但包含逗号(由regexr上的Luke Sheppard提供)

    1. val i=0; 不是scala-ish / functional 。我们可以在for comprehension中用zipWithIndex替换它:

      for ((line, count) <- bufferedSource.getLines.zipWithIndex)

    2. 您可以创建&#34;全局矩阵&#34;通过从每一行(val Array (...))中提取元素并将它们作为for-comprehension块(yield)的值返回:

    3. 看起来像是:

      for ((line, count) <- bufferedSource.getLines.zipWithIndex) yield {
        val Array(theme,title,artist,year,spotify_url) = line....
        ...
        (theme,title,artist,year,spotify_url)
      }
      

      这是完整的解决方案:

      val bufferedSource = io.Source.fromFile("/tmp/Top_1_000_Songs_To_Hear_Before_You_Die.csv")
      val years = Array.ofDim[String](1000, 1)
      
      val regex = ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))"
      
      val iteratorMatrix = for ((line, count) <- bufferedSource.getLines.zipWithIndex) yield {
        val Array(theme,title,artist,year,spotify_url) = line.split(regex, -1).map(_.trim)
        years(count) = Array(year)
        (theme,title,artist,year,spotify_url)
      }
      
      // will actually consume the iterator and fill in globalMatrix AND years
      val globalMatrix = iteratorMatrix.toList
      

答案 1 :(得分:0)

这是一个从CSV中获取col列的函数。对于任何空行或其他条件,此处没有错误处理。这是一个概念证明,因此您可以根据需要添加自己的错误处理。

val years = (fileName: String, col: Int) => scala.io.Source.fromFile(fileName)
    .getLines()
    .map(_.split(",")(col).trim())

如果您希望将文件内容保存在地图中,请提供以下建议。再一次,没有错误处理只是概念验证。

val yearColumn = 3

val fileName = "Top_1_000_Songs_To_Hear_Before_You_Die.csv"

def lines(file: String) = scala.io.Source.fromFile(file).getLines()

val mapRow = (row: String) => row.split(",").zipWithIndex.foldLeft(Map[Int, String]()){
  case (acc, (v, idx)) => acc.updated(idx,v.trim())}

def mapColumns = (values: Iterator[String]) =>
  values.zipWithIndex.foldLeft(Map[Int, Map[Int, String]]()){
    case (acc, (v, idx)) => acc.updated(idx, mapRow(v))}

val parser = lines _  andThen mapColumns

val matrix = parser(fileName)

val years = matrix.flatMap(_.swap._1.get(yearColumn))

这将构建一个Map[Int,Map[Int, String]],您可以在其他地方使用。映射的第一个索引是行号,内部映射的索引是列号。 yearsIterable[String],其中包含年份值。

答案 2 :(得分:0)

考虑在创建集合的同时将内容添加到集合中,而不是首先分配空间,然后更新它;比如像这样,

val rawSongsInfo = io.Source.fromFile("Top_Songs.csv").getLines

val cols = for (rsi <- rawSongsInfo) yield rsi.split(",").map(_.trim)
val years = cols.map(_(3))