2012-09-20 72 views
9

有沒有更好的方法來編寫下面的代碼?scala更好的地圖語法getOrElse

val t = map.get('type).getOrElse(""); 
if (t != "") "prefix" + t; 

感興趣的內嵌代碼類似

val t = map.get('type).getOrElse("").???? 

回答

26

Map都有自己getOrElse方法,所以你可以寫:

val t = map.getOrElse('type, "") 

這樣達成了同樣的事情在你的第一個例子中定義了t


爲了解決您的評論:如果您知道您的地圖永遠不會包含空字符串的值,可以使用下面的添加"prefix"

map.get('type).map("prefix" + _).getOrElse("") 

或者,如果你是使用Scala的2.10:

map.get('type).fold("")("prefix" + _) 

如果地圖可以""值,這個版本會表現有點differentl因爲它會爲這些值添加前綴。如果你想要完全一樣的行爲,你在一個班輪版本,你可以寫:

map.get('type).filter(_.nonEmpty).map("prefix" + _).getOrElse("") 

這可能是沒有必要的,但是,這聽起來像你不要指望有空字符串在你的地圖中。

+0

剛開始學習Scala,所以這是非常有用的。那第二行呢?有沒有辦法將它們結合起來?如果我對你有所幫助 – pbaris

+0

」 」。但是,@ om-nom-nom建議按我的預期工作 – pbaris

+0

聽起來你的'map'有'Any'作爲它的值的類型,這很可能會讓你陷入困境。你如何定義它? –

4

還值得注意的是,在某些情況下,您可以用一個.withDefaultValue呼叫替換多個常用.getOrElse用法。

val map = complexMapCalculation().withDefaultValue("") 

val t = map('type) 

我不會說這是每次都應該做的事,但它可以得心應手。

1

您也可以使用Scalaz Zero類型類別,以便您的代碼如下所示。一元運算符定義在OptionW上。

val t = ~map.get('type)     // no prefix 
val t = ~map.get('type).map("prefix"+_) // prefix 

下面是一個例子會話:

scala> import scalaz._; import Scalaz._ 
import scalaz._ 
import Scalaz._ 

scala> val map = Map('type -> "foo") 
map: scala.collection.immutable.Map[Symbol,java.lang.String] = Map('type -> foo) 

scala> ~map.get('type) 
res3: java.lang.String = foo 

scala> ~map.get('notype) 
res4: java.lang.String = "" 

scala> ~map.get('type).map("prefix"+_) 
res5: java.lang.String = prefixfoo 

scala> ~map.get('notype).map("prefix"+_) 
res6: java.lang.String = "" 
-1

雖然讀的書Play for Scala,我拿起控制器中的定義,該代碼段,這可能是一個更好的語法getOrElse

def show(ean: Long) = Action { implicit request => 

    Product.findByEan(ean).map { product => 
    Ok(views.html.products.details(product)) 
    }.getOrElse(NotFound) 

} 

其中,在Product.findByEan(EAN:龍)定義像

def findByEan(ean: Long) = products.find(_ean == ean) 
+1

雖然這個語法很好用,但恐怕這個問題是關於不同的地圖 - 你說的是地圖集合遍歷,而這是關於[地圖集合](http://www.scala-lang.org/api/current/index.html#scala.collection.Map)。 – Suma