我试图从映射的整数列表中获取平均值,然后在请求时将该值返回给用户。 这是我目前的代码有问题,我做错了什么?我已经包含了我的功能,可以找到尾部的最后一个元素。
// *******************************************************************************************************************
// 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
类型答案 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
基本上需要时间。