2014-10-28 73 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