2016-11-12 37 views
-2

我試圖從int的映射列表中獲取平均值,然後在請求時將該值返回給用戶。 這是我目前的代碼有問題,我做錯了什麼?我已經包含了我的功能來查找尾部的最後一個元素,這很有效。從int的映射列表中查找平均值

// ******************************************************************************************************************* 
    // 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

請告訴我問題在哪裏。你有沒有編譯錯誤?你得到錯誤的結果了嗎?你的data.txt包含什麼? – pamu

+0

data.txt中的數據如何佈置? – pamu

+0

試圖包括所有相關的東西,忘記了數據文件...順利的一個安德烈,已添加到包括錯誤,我得到@ pamu –

回答

1

averageStockLevel函數返回平均值爲Int(返回類型爲(String, Int)),而在average中完成的計算返回Double

所以,你要麼需要計算Double轉換爲IntaverageStockLevel(例如,通過做average(_).toInt),或者你可以改變的averageStockLevel返回類型(String, Double)。後一種變體顯然更好,因爲你不會失去平均值的精確度。

def averageStockLevel (stock: String): (String, Double) = { 
    (stock, mapdata.get(stock).map(average).getOrElse(0.0)) 
} 

這工作,但它是否是在一個缺少鍵的情況下返回0.0一個好主意,是你來決定。另一種可能性是省略getOrElse部分並返回Option[(String,Double)]

除此之外,你的代碼是相當複雜的。 findLastaverage可以定義要容易得多(這是不是真的值得尋找的最後一個元素創建自己的功能,但爲了完整起見...):

// 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 

另一個想法是,以取代ListVector。對於諸如.size.last之類的操作,List需要線性時間,而Vector基本上需要恆定的時間。

+0

謝謝你解釋爲什麼它沒有工作,真的幫助我瞭解。顯然不能返回一個int作爲int,並感謝解決方案! –