2016-08-16 54 views
1

的平均我是新來的Scala和我在這個結構圖的listbuffer:ListBuffer(Note([email protected],Some(2)), Note([email protected],Some(3)))計算期權的詮釋與斯卡拉

我想計算的平均(一些(2),有些(3 )) 當我計算總和我得到這個錯誤Overloaded method value [+] cannot be applied to (Any)

var sum = 0 
    for (note <- notes) 
      sum += note.note.getOrElse("existe") 

回答

2

你有note財產Option[Int]。當您撥打getOrElse(String)時,編譯器會計算出結果類型爲Any,這是IntString的最接近的超類。如您所知,Any沒有+方法。

您可以重構代碼以下列方式:

val numbers = notes.flatMap(_.note) // or notes.map(_.note.getOrElse(0)) if you want to consider empty notes 

numbers.sum/numbers.length 
+1

注意與此解決方案,以避免'java.lang.ArithmeticException:/由zero'時'numbers.length == 0「,即沒有音符時。 – Eric

+0

@Eric不錯的提示! –

2

您可以使用foldLeft來計算一個解析的總和。如flatMap然後sum方法採取列表的兩個分析。

val sum = notes.foldLeft(0)({ case (acc, note) => acc + note.note.getOrElse(0) }) 

還...你是如何定義你的情況AVG,

// lets say you have this list of notes 
val notes = ListBuffer(Note("[email protected]", Some(2)), Note("[email protected]", Some(3)), Note("test.gmail.com", None)) 

// Now what is supposed to be your avg 
// Do you want to consider a None as 0 or do you want to ignore it 
// is it -> (3 + 2 + 0)/3 = 5/3 
// or is it -> (3 + 2)/2 = 5/2 

// If you want to consider a None as 0 then, 
val (sum, count) = notes.foldLeft((0, 0))({ 
    case ((acc, count), note) => { 
    note.note.map(i => (i + acc, count + 1)).getOrElse((acc, count + 1)) 
    } 
}) 
val avg = sum/count 

// if you want to ignore all None then, 
val (sum, count) = notes.foldLeft((0, 0))({ 
    case ((acc, count), note) => { 
    note.note.map(i => (i + acc, count + 1)).getOrElse((acc, count)) 
    } 
}) 
val avg = sum/count