2017-01-14 2 views
0

Ich bin auf der Suche nach einer Funktion, die wie collect aussieht. Diese Funktion muss das Element beibehalten, das das Prädikat nicht erfüllt. Dieses Verhalten könnte unter Verwendung von map ausgedrückt werden. Beispiel:Welche Funktion hat das gleiche Verhalten wie Collect, aber behalten Sie die Elemente, die nicht das Prädikat erfüllen

@ (0 to 10).map{ 
     case e if e > 5 => e * e 
     case e   => e // I want to keep elements to does not satisfy the predicate ! 
    } 
res3: collection.immutable.IndexedSeq[Int] = Vector(0, 1, 2, 3, 4, 5, 36, 49, 64, 81, 100) 

Ich möchte in der Lage sein, diese Funktion wie folgt zu schreiben:

@ (0 to 10).map{ 
     case e if e > 5 => e * e 
    } 
scala.MatchError: 0 (of class java.lang.Integer) 
    $sess.cmd4$$anonfun$1.apply$mcII$sp(cmd4.sc:1) 
    $sess.cmd4$$anonfun$1.apply(cmd4.sc:1) 
    $sess.cmd4$$anonfun$1.apply(cmd4.sc:1) 
    scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234) 
    scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234) 
    scala.collection.immutable.Range.foreach(Range.scala:160) 
    scala.collection.TraversableLike$class.map(TraversableLike.scala:234) 
    scala.collection.AbstractTraversable.map(Traversable.scala:104) 
    $sess.cmd4$.<init>(cmd4.sc:1) 
    $sess.cmd4$.<clinit>(cmd4.sc:-1) 

Leider habe ich keine Funktion gefunden, die eine PartialFunction nimmt MatchErrors zu vermeiden.

Kennen Sie eine Funktion mit einem solchen Verhalten?

Antwort

2

Ich glaube nicht, dass es eine vordefinierte Methode ist, das tut, was Sie wollen, aber Sie können einen PartialFunction ‚s .applyOrElse verwenden, es zu tun:

scala> implicit class MySeq[A](r: Seq[A]) { 
     def mapIfDefined(f: PartialFunction[A, A]): Seq[A] = { 
      r.map(f.applyOrElse[A, A](_, identity)) 
     } 
     } 

scala> (0 to 10).mapIfDefined{ 
     case e if e > 5 => e * e 
     } 
res1: Seq[Int] = Vector(0, 1, 2, 3, 4, 5, 36, 49, 64, 81, 100) 
0

Wenn ich nicht irre, collect tut genau das, was du fragst:

scala> List(1,2,3,4,5,6,7,8,9,10).collect { 
    | case e if e > 5 => e * e 
    | case e => e 
    | } 
res0: List[Int] = List(1, 2, 3, 4, 5, 36, 49, 64, 81, 100) 
+0

stimme ich zu. 'collect' und' map' (vgl. mein erstes Code-Snippet) können hier den Job erledigen. Aber mein Ziel war es, diese Linie zu vermeiden: "case e => e". – Dnomyar

+0

Warum nicht einfach 'List (...) schreiben. Map {e => if (e> 5) e * e sonst e}', dann? Ich denke, es macht mehr Sinn, als eine implizite 'mapIfDefined' Methode zu verwenden, um eine einfache 'else'-Klausel zu ersetzen. – Eric

Verwandte Themen