Reputation: 10303
Suppose I have a function f(n:Int):Option[String]
. I would like to find such 1 <= k <= 10
that f(k)
is not None
. I can code it as follows:
(1 to 10).find(k => f(k).isDefined)
Now I would like to know both k
and f(k)
.
val k = (1 to 10).find(f(_).isDefined) val s = f(k)
Unfortunately, this code invokes f(k)
twice. How would you find k
and f(k)
at once ?
Upvotes: 2
Views: 232
Reputation: 9791
A slightly more verbose version of Tomasz Nurkiewicz's solution:
xs = (1 to 10).view
xs zip { xs map { f(_) } } collectFirst { case (k, Some(v)) => (k, v) }
Upvotes: 2
Reputation: 36229
A bit shorter - just map and find:
// for testing
def f (n: Int): Option [String] =
if (n > 0) Some ((List.fill (n) ("" + n)).mkString) else None
(-5 to 5).map (i => (i, f(i))).find (e => e._2 != None)
// result in REPL
res67: Option[(Int, Option[String])] = Some((1,Some(1)))
Upvotes: 2
Reputation: 340733
My first try would be:
(1 to 10).view map {k => (k, f(k))} find {_._2.isDefined}
The use of view
avoids creating intermediate map
. Or even better with pattern matching and partial function:
(1 to 10).view map {k => (k, f(k))} collectFirst {case (k, Some(v)) => (k, v)}
This returns Option[(Int, java.lang.String)]
(None
if no element satisfying f
is found).
You might also experiment with .zipWithIndex
.
Upvotes: 9