从映射的int列表中查找平均值

时间:2016-11-12 09:15:55

标签: scala mapping

我试图从映射的整数列表中获取平均值,然后在请求时将该值返回给用户。 这是我目前的代码有问题,我做错了什么?我已经包含了我的功能,可以找到尾部的最后一个元素。

// *******************************************************************************************************************
  // application logic
    // read data from file
  val mapdata = readFile("data.txt")




  // *******************************************************************************************************************
  // UTILITY FUNCTIONS
  //GETS THE DATA FROM THE DATA.TXT
  def readFile(filename: String): Map[String, List[Int]] = {
    processInput(Source.fromFile(filename).getLines)
  }
  def processInput(lines: Iterator[String]): Map[String, List[Int]] = {
    Try {
      lines.foldLeft(Map[String, List[Int]]()) { (acc, line) =>

        val splitline = line.split(",").map(_.trim).toList
        acc.updated(splitline.head, splitline.tail.map(_.toInt))
      }
    }.getOrElse {
      println("Sorry, an exception happened.")
      Map()
    }
  }



  //functionality to find the last tail element
  def findLast(list:List[Int]):Int = {
    if(list.tail == Nil)
      list.head
    else
      findLast(list.tail)
  }

  //Function to find the average
  def average(list:List[Int]):Double =
    list.foldLeft(0.0)(_+_) / list.foldLeft(0)((r,c)=>r+1)



 //Show last element in the list, most current WORKS
  def currentStockLevel (stock: String): (String, Int) = {
    (stock, mapdata.get (stock).map(findLast(_)).getOrElse(0))
  }

  //Show last element in the list, most current DOES NOT WORK
  def averageStockLevel (stock: String): (String, Int) = {
    (stock, mapdata.get (stock).map(average(_)).getOrElse(0))
  }

我的txt文件

SK1, 9, 7, 2, 0, 7, 3, 7, 9, 1, 2, 8, 1, 9, 6, 5, 3, 2, 2, 7, 2, 8, 5, 4, 5, 1, 6, 5, 2, 4, 1
SK2, 0, 7, 6, 3, 3, 3, 1, 6, 9, 2, 9, 7, 8, 7, 3, 6, 3, 5, 5, 2, 9, 7, 3, 4, 6, 3, 4, 3, 4, 1
SK4, 2, 9, 5, 7, 0, 8, 6, 6, 7, 9, 0, 1, 3, 1, 6, 0, 0, 1, 3, 8, 5, 4, 0, 9, 7, 1, 4, 5, 2, 8
SK5, 2, 6, 8, 0, 3, 5, 5, 2, 5, 9, 4, 5, 3, 5, 7, 8, 8, 2, 5, 9, 3, 8, 6, 7, 8, 7, 4, 1, 2, 3

我得到的错误是AnyVal类型的表达式不符合Int

类型

1 个答案:

答案 0 :(得分:1)

您的averageStockLevel函数将平均值返回为Int(返回类型为(String, Int)),而average中的计算返回Double }。

因此,您需要将计算出的Double转换为Int内的averageStockLevel(例如,通过执行average(_).toInt),或者您可以更改{{的返回类型1}}到averageStockLevel。后一种变体显然是更好的变体,因为你不会失去平均值的精确度。

(String, Double)

这是有效的,但是如果在丢失密钥的情况下返回def averageStockLevel (stock: String): (String, Double) = { (stock, mapdata.get(stock).map(average).getOrElse(0.0)) } 是否是一个好主意,则由您自行决定。另一种可能性是省略0.0部分并返回getOrElse

除此之外,您的代码非常复杂。 Option[(String,Double)]findLast可以更容易定义(创建自己的函数来查找最后一个元素并不值得,但为了完整性...):

average

另一个想法是将// will throw an exception for empty lists, but so does your current code def findLast(list:List[Int]) = list.last def average(list:List[Int]): Double = list.sum.toDouble / list.size 替换为List。对于Vector.size等操作,.last需要线性时间,而List基本上需要时间。