2013-10-14 3 views
0

이 코드의 모든지도는 전체 코드의 import 문으로 인해 변경 가능한지도입니다. nGramGetter.getNGrams(...) 메서드 호출은 Map [String, Int]을 반환합니다.스칼라가 변경 가능한지도의 값을 변경할 수 없습니다. [Char, Map [Int, Double]] 기본값이

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)))) 
    } 

I 출력을 확인 (각 키의 키 값과 개별 문자를 인쇄) 몇 인쇄 제표를 scores(char)(i) += nGram._2 라인을 교체했으며, 메소드 호출은 빈 목록을 반환하지 않습니다. 그러나 scores의 크기를 인쇄하는 줄은 0을 인쇄합니다. 이전에 빈도 맵을 채우는 데이 메서드를 정확히 사용했는지는 거의 확실하지만 이번에는 맵이 항상 비어 있습니다. withDefaultwithDefaultValue으로 변경하고 현재 함수 리터럴의 결과를 인수로 전달했습니다. withDefaultwithDefaultValue을 모두 Map[Int, Double](1->0.0,2->0.0,3->0.0,4->0.0)으로 시도했습니다. 저는 스칼라 멍청한 놈입니다. 아마도 문제의 원인이되는 언어에 대해 이해하지 못했을 것입니다. 어떤 생각이 잘못된거야?

답변

2

withDefaultwithDefaultValue 메서드는 맵을 변경하지 않습니다. 대신 그들은 단순히 기본값을 반환합니다. 의 그것이 잘못 어디 문법 설탕을 확인하기 위해 문을 형성 제거하자 scores.apply(char) 이후

이제
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) 

이 존재하지 않는, 기본은 Map[Int, Double]().withDefaultValue(0.0)을 반환하고, 그지도가 수정됩니다. 불행히도 메서드가 호출되지 않았으므로 scores에 할당되지 않습니다. 아래에서이 코드를 시도해보십시오. 테스트되지 않았지만 제대로 작동하지 않아야합니다.

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

이제 완벽하게 작동합니다. 정말 고마워! – user2073068