Scala无法使用默认值更改可变Map [Char,Map [Int,Double]]中的值

时间:2013-10-14 03:44:57

标签: scala maps default-value scala-collections mutable

由于完整代码中较早的import语句,此代码中的所有映射都是可变映射。 nGramGetter.getNGrams(...)方法调用返回Map [String,Int]。

  def train(files: Array[java.io.File]): Map[Char, Map[Int, Double]] = {
    val scores = Map[Char, Map[Int, Double]]().withDefault( x => Map[Int, Double]().withDefaultValue(0.0)) 

    for{
      i <- 1 to 4
      nGram <- nGramGetter.getNGrams(files, i).filter( x => (x._1.size == 1 || x._2 > 4) && !hasUnwantedChar(x._1) )
      char <- nGram._1
    } scores(char)(i) += nGram._2
    println(scores.size)
    val nonUnigramTotals = scores.mapValues( x => x.values.reduce(_+_)-x(1) )    

    val unigramTotals = scores.mapValues( x => x(1) )

    scores.map( x => x._1 -> x._2.map( y => y._1 -> (if(y._1 > 1) y._2/unigramTotals(x._1) else (y._2-nonUnigramTotals(x._1))/unigramTotals(x._1)) ) )
  }

我已将scores(char)(i) += nGram._2行替换为一些打印语句(打印每个键中的键,值和单个字符)以检查输出,并且方法调用不返回空列表。但是,打印scores大小的行打印为零。我几乎可以肯定我之前使用过这种方法来填充频率图,但这次,地图总是空出来的。我已将withDefault更改为withDefaultValue并将当前函数文字的结果作为参数传递。我使用withDefault尝试了withDefaultValueMap[Int, Double](1->0.0,2->0.0,3->0.0,4->0.0)。我是一个Scala noob,所以也许我只是不明白导致问题的语言。知道什么是错的吗?

1 个答案:

答案 0 :(得分:2)

方法withDefaultwithDefaultValue不会更改地图。相反,它们只返回一个默认值。让我们从你的陈述中删除语法糖,看看它出错了:

scores(char)(i) += nGram._2
scores(char)(i) = scores(char)(i) + nGram._2
scores.apply(char)(i) = scores.apply(char)(i) + nGram._2
scores.apply(char).update(i, scores.apply(char).apply(i) + nGram._2)

现在,由于scores.apply(char)不存在,因此会返回默认值Map[Int, Double]().withDefaultValue(0.0) 地图会被修改。不幸的是,它从未被分配到scores,因为没有调用update方法。请尝试下面的代码 - 它未经测试,但要让它工作起来应该不难:

scores(char) = scores(char) // initializes the map for that key, if it doesn't exist
scores(char)(i) += nGram._2