How to find a matching element in a list and map it in as an Scala API method?
Solution 1
How about using collect?
// Returns List(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 }
However that will return all matches and not just the first one.
The better answer would have been, based on Scala 2.9:
// Returns Some(66)
List(1, 2, 3) collectFirst { case i if (i * 33 % 2 == 0) => i * 33 }
The solution suggested in the comments to append a head
to get a Scala 2.8 version of that is not very efficient, I'm afraid. Perhaps in that case I would stick to your own code. In any case, in order to make sure it returns an option, you should not call head
, but headOption
.
// Returns Some(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 } headOption
Solution 2
If you don't want to do your map()
operation multiple times (for instance if it's an expensive DB lookup) you can do this:
l.view.map(_ * 33).find(_ % 2 == 0)
The view
makes the collection lazy, so the number of map()
operations is minimized.
Solution 3
Hey look, it's my little buddy findMap
again!
/**
* Finds the first element in the list that satisfies the partial function, then
* maps it through the function.
*/
def findMap[A,B](in: Traversable[A])(f: PartialFunction[A,B]): Option[B] = {
in.find(f.isDefinedAt(_)).map(f(_))
}
Note that, unlike in the accepted answer, but like the collectFirst
method mentioned in one of its comments, this guy stops as soon as he finds a matching element.
Related videos on Youtube
agilefall
Scala/Javascript/Java developer at a startup outside of Portland Oregon.
Updated on March 09, 2020Comments
-
agilefall about 4 years
Is there a method to do the following without doing both methods:
find
andmap
?val l = 0 to 3 l.find(_ * 33 % 2 == 0).map(_ * 33) // returns Some(66)
-
Seth Tisue about 13 yearsthis traverses the entire list
-
lisak over 9 yearsI think this is the most correct answer to this question. The others are useless in most cases because the operation must be executed twice.
-
Sebastien Lorber about 8 yearsTHANKS! exactly what I wanted never heard of this views before (but used somethi,ng like that with Java/Guava in the past)!