2014-10-28 117 views
1

我想在迭代這個斯卡拉更新值,而迭代

case class WordCount(name: String, 
       id: Int, 
       var count: Double, 
       var links: scala.collection.mutable.HashMap[String, Double], 
       var ent: Double) { 

    def withEnt(v: Double): WordCount = {println(s"v: $v"); copy(ent = v)} 
} 

var targets = mutable.HashMap[String, WordCount]() 

功能calEnt更新地圖[字符串,字計數]值是:

def calEnt(total: Double, links: scala.collection.mutable.HashMap[String, Double]): Double = { 
    var p: Double = 0.0 
    var ent: Double = 0.0 
    links.map(d => { 
     p = d._2/total 
     ent -= p * Math.log(p) 
    }) 
    return ent 
    } 

而且我使用的是:

targets.map(m => m._2.withEnt(calEnt(m._2.count, m._2.links))) 

的迭代地圖,計算新的價值ent與此更新。我可以在控制檯中注入新的值,但它不在地圖內部設置。有什麼辦法做到這一點?請。

+1

這幾乎是** **從來沒有意義的具有可變數據結構在'var' - 無論是使用'具有可變數據結構的val,或具有不可變數據結構的var;另外,請注意,使用'var' + immutable;看到http://stackoverflow.com/questions/11386559/val-mutable-versus-var-immutable-in-scala – 2014-10-28 20:45:13

回答

3

map方法不會修改您的targets HashMap。它會返回一個新的,修改後的HashMap。試試這個:

targets = targets.map(m => (m._1, m._2.withEnt(calEnt(m._2.count, m._2.links)))) 

請注意,我們映射到一對密鑰m._1和修改後的值。不只是價值觀。

+0

我明白了,那麼我應該怎麼做才能更新值而不創建新的HashMap? – lantis 2014-10-28 20:22:38

+0

只需遍歷所有鍵並更新它們的值。 'targets.keys'將返回密鑰。所以你按照下面的方式去做:'for(k < - targets.keys)targets(k)=/*你的新值* /'。 – 2014-10-28 20:30:25

+0

我明白了。非常感謝! =) – lantis 2014-10-28 20:32:02

3

使用的foreach:

targets.foreach(m => targets(m._1) = m._2.withEnt(calEnt(m._2.count, m._2.links))) 

自給例如:

val m = scala.collection.mutable.HashMap[Int, Int](1 -> 1, 2 -> 2) 
println(m) 
m.foreach(p => m(p._1) = p._2 + 1) 
println(m) 
+0

謝謝!對不起,但我沒有足夠的聲望投票你的答案是有用的,但真的很有用 – lantis 2014-10-28 20:37:10