2017-06-07 72 views
0

我正面臨一個問題: 我想更改其中的一個元素,但代碼正在更改所有元素。 我一定在做錯事。 這是我有:Scala:更改地圖列表中的值

var critics: Map[String, List[(String, Double)]] = Map(
    "First" -> List(("a", 1.0), ("b", 2.0)), 
    "Second" -> List(("c", 3.0), ("d", 4.0)) 
) 

    def setNewRating(keyMap: String, param1: String, newRating: Double) = { 
    val newList = critics(keyMap).map{case (param1, _) => (param1, newRating); case x => x} 
    critics = critics + (keyMap -> newList) 
    } 

    println(critics) 

    setNewRating("First", "b", 5.0) 

    println(critics) 

所以,我正在尋找的關鍵「第一」,讓我想改變「B」爲2.0至5.0,但我得到的結果是列表:

critics: Map[String,List[(String, Double)]] = Map(First -> List((a,1.0), (b,2.0)), Second -> List((c,3.0), (d,4.0))) 
setNewRating: (keyMap: String, param1: String, newRating: Double)Unit 
Map(First -> List((a,1.0), (b,2.0)), Second -> List((c,3.0), (d,4.0))) 
Map(First -> List((a,5.0), (b,5.0)), Second -> List((c,3.0), (d,4.0))) 

該代碼改變了所有的值!

在此先感謝,

回答

1

你需要把param1在反引號:

def setNewRating(keyMap: String, param1: String, newRating: Double) = { 
    val newList = critics(keyMap) 
    .map { 
     case (`param1`, _) => param1 -> newRating 
     case x => x 
    } 
    critics = critics + (keyMap -> newList) 
    } 

的問題是,case (param1, _)表示「匹配任何內容,並將該值存儲到新的局部變量param1」。這不是你想要的。

case (`param1`, _) => 

另一方面,意味着「匹配與外部變量param1相同的值」。或者,如果您將param1重命名爲Param1,它也會起作用(顯然,scala匹配假定以大寫字母開頭的所有內容都是常量)。我並不是建議你這樣做,只是爲了完整性而提及它。只需使用反引號。

(此外,使用var這樣令我生厭,你真的應該找到一種方法,以避免它,但是這不是你的問題...)

+0

是的,我也不喜歡這個變種的事情,但我不知道我該怎麼做一個「階路」(我有一個Java背景) !也許從該方法返回一個新的地圖? – MLeiria

+0

是的,返回一張新地圖,就是這樣。另外,將它作爲輸入傳遞將是一個好主意(「好」功能不會引起副作用,並且不依賴外部數據):'println(setNewRating(critters,「First」,「b」,5 ))' – Dima

1

這應該工作。您在案例條款.map{case (param1, _)中使用的param1與參數中定義的變量param1不同。它是一個新變量param1,它被分配了Tuple2的第一個元素的值,該值影響方法參數。

def setNewRating(keyMap: String, param1: String, newRating: Double) = { 
    val newList = critics(keyMap) map { 
    case (x, _) if x == param1 => (param1, newRating) 
    case x => x 
    } 
    critics = critics + (keyMap -> newList) 
} 
0

如果你願意從List更改爲Set ,你可能會錯過MultiMap的特質。

具有分配給鍵的多個值的可變映射的特徵。

這個類通常用作mixin。它將映射A到設置[B]對象的映射轉換爲映射A到B對象的多映射。

您可以找到參考here