2012-11-14 49 views
1

我想下面的函數:採取以下參數:如何用不可變集合和適當的語句寫適當的Scala?

  • def filters: Map[String, String]
  • (從的Request.QueryString)
  • def key: String

..如果queryString包含key在參數中指定def queryString: Map[String, Seq[String]] ,我想將相應的值添加到filters

的工作職能是:

private def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] = { 
    var updatedFilters: Map[String, String] = filters 

    if (queryString.contains(key)) { 
    updatedFilters = updatedFilters ++ Map(key -> queryString.get(key).get.head) 
    } 

    updatedFilters 
} 

這看起來可怕的,對不對?

由於if語句在Scala中返回的東西,我期待的東西沿着這些線路更多:

private def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] = { 
    if (queryString.contains(key)) { 
    filters ++ Map(key -> queryString.get(key).get.head) 
    } 
} 

但是,這並不編譯,錯誤的是:

類型不匹配;發現:單位要求:地圖[字符串,字符串]

+0

Scala沒有一個if語句 - 它有一個if表達式。正如你已經說過的,它們返回一個值 - 一個聲明是一個不返回任何內容的指令的名稱。 – sschaef

回答

4

你的函數簽名指出Map[String, String]應返回,但...等一下,想象,如果的queryString不包含的關鍵是什麼?好吧,看起來什麼都不會返回,並且單元在斯卡拉中什麼也不是(至少沒有任何一種)。

要解決,你需要提供這個問題的選擇:

private def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] = { 
    if (queryString.contains(key)) { 
     filters ++ Map(key -> queryString.get(key).get.head) 
    } else filters 
    } 

的方式,函數名真讓我害怕

+0

謝謝!正是我想要的。塞繆爾的解決方案是一個班輪,但對新手來說看起來也更難理解。 – Blackbird

5

您可以使用更多的單子

queryString.get(key) map { v => filters ++ Map(key -> v.head) } getOrElse filters

這是你想要的。

5

這裏是一個更地道的實現不使用if

def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] = 
    filters ++ queryString.get(key).map(key -> _.head) 
+0

你不是在這裏缺少一個地圖嗎?你不能++一對地圖,你能嗎? –

+0

'Map [K,V] .get(key)'返回一個'Option [V]',它基本上只是一個限制爲0或1的集合。你可以在它上面使用'++'和'map'它就像其他收藏一樣。 Scala 2.10甚至向Option添加了摺疊操作。 – DaoWen

+0

有一個從Option [A]到Iterable [A]的隱式轉換,'++'允許你在Map [A​​,B]附加一個'Iterable [(A,B)]' '。 –