Frage

Mit Scala 2.7.7:

Wenn ich eine Liste von Optionen, kann ich glätte sie mit einem for-Verständnis:

val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)

scala> for (opt <- listOfOptions; string <- opt) yield string
res0: List[java.lang.String] = List(hi)

Ich weiß nicht, wie diese Art, und würde lieber einen HOF verwenden. Dieser Versuch ist zu ausführlich akzeptabel zu sein:

scala> listOfOptions.flatMap(opt => if (opt.isDefined) Some(opt.get) else None)
res1: List[java.lang.String] = List(hi)

Intuitiv würde ich folgende zur Arbeit zu erwarten, aber es funktioniert nicht:

scala> List.flatten(listOfOptions)
<console>:6: error: type mismatch;
 found   : List[Option[java.lang.String]]
 required: List[List[?]]
       List.flatten(listOfOptions)

Auch die folgende scheint, wie es funktionieren soll, aber nicht:

scala> listOfOptions.flatMap(_: Option[String])
<console>:6: error: type mismatch;
 found   : Option[String]
 required: (Option[java.lang.String]) => Iterable[?]
       listOfOptions.flatMap(_: Option[String])
                          ^

Das Beste, was ich mit oben kommen kann ist:

scala> listOfOptions.flatMap(_.toList)         
res2: List[java.lang.String] = List(hi)

... aber ich würde viel lieber nicht auf eine Liste, um die Option zu konvertieren. Das scheint klobig.

Jede Beratung?

War es hilfreich?

Lösung

In Scala 2.8, abflachen Arbeit:


Welcome to Scala version 2.8.0.RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)

scala> listOfOptions flatten
res0: List[java.lang.String] = List(hi)

Das funktioniert nicht in 2.7.7, aber:


Welcome to Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).

scala> val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)

scala> listOfOptions.flatten
:6: error: no implicit argument matching parameter type (Option[java.lang.String]) => Iterable[Nothing] was found.
       listOfOptions.flatten

Die Sammlungen Bibliothek wurde neu gestaltet und hat eine Menge in 2,8 verbessert, so vielleicht möchten Sie vielleicht versuchen, die neuesten Scala 2.8 RC zu verwenden und sehen, ob es für Sie einfach zu nutzen macht.

Wenn Sie wirklich nicht wollen, die ToList Methode verwenden, ich denke, man kann es auch so schreiben:


scala> listOfOptions.flatMap(o => o)
res: List[java.lang.String] = List(hi)

Auch nicht eine Sache der Schönheit vielleicht, aber zumindest das funktioniert in 2.7.7.

Andere Tipps

Um Arjan Antwort zu ergänzen, in Scala 2.7.7 können Sie List#flatten verwenden, aber Sie brauchen, um Hilfe aus der Art Rückschließer:

Welcome to Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)

scala> listOfOptions.flatten[String]                   
res0: List[String] = List(hi)

scala> val x: List[String] = listOfOptions.flatten
x: List[String] = List(hi)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top