2012-09-20 20 views
9

Czy istnieje lepszy sposób na zapisanie kodu poniżej?scala lepsza składnia mapy getOrElse

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

być zainteresowany w kodzie inline coś jak

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

Odpowiedz

26

Map ma swoją własną metodę getOrElse, więc można po prostu napisać co następuje:

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

który wykonuje to samo, co definicja t w twoim pierwszym przykładzie.


Aby rozwiązać swój komentarz: Jeśli wiadomo, że mapa nie będzie zawierała pusty łańcuch jako wartość, można użyć następujących dodać "prefix":

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

Lub, jeśli jesteś używając Scala 2.10:

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

Jeśli mapa może mieć "" wartości, ta wersja będzie zachowywać się trochę differentl y niż twój, ponieważ doda przedrostek do tych wartości. Jeśli chcesz dokładnie takie samo zachowanie jak w wersji jedno-liner, można napisać następujące:

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

To prawdopodobnie nie jest konieczne, choć-to brzmi jak nie spodziewasz się mieć pustych strun na twojej mapie.

+0

Właśnie rozpoczął naukę Scala, więc jest to bardzo przydatne. A co z drugą linią. Czy istnieje sposób na ich połączenie? – pbaris

+1

@pbaris 'val t = map.get (" type) .map (k => "prefix" + k) .getOrElse ("") 'jeśli mam rację –

+0

kompilator mówi" wartość nonEmpty nie jest członkiem Any ".Ale co @ om-nom-nom zasugerowało działanie tak, jak się spodziewałem – pbaris

4

Warto również zauważyć, że w niektórych przypadkach można zastąpić wiele popularnych zastosowań .getOrElse jednym połączeniem .withDefaultValue.

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

val t = map('type) 

Nie powiedziałbym, że jest to coś, co należy zrobić za każdym razem, ale może być przydatne.

1

Można również użyć kodu typowego Scalaz Zero, aby kod wyglądał jak poniżej. Operator jednoargumentowy jest zdefiniowany na OptionW.

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

Oto przykład sesja:

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

Czytając książkę Play for Scala, podniosłem ten fragment kodu, który został zdefiniowany w sterowniku, który może być lepszym składnia getOrElse.

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

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

} 

W jakich The Product.findByEan (EAN: Long) został zdefiniowany jak

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

Chociaż ta składnia jest dobra i użyteczna, obawiam się, że to pytanie dotyczy innej mapy - mówisz o przechwytywaniu kolekcji map, podczas gdy chodzi o [Kolekcja map] (http://www.scala-lang.org/api/current/index.html#scala.collection.Map). – Suma

Powiązane problemy