假设我有一个函数f(n:Int):Option[String]
。我想找到1 <= k <= 10
不是f(k)
的{{1}}这样的None
。我可以按如下方式编写代码:
(1 to 10).find(k => f(k).isDefined)
现在我想知道 k
和f(k)
。
val k = (1 to 10).find(f(_).isDefined) val s = f(k)
不幸的是,此代码会两次调用f(k)
。您如何一次找到k
和f(k)
?
答案 0 :(得分:9)
我的第一次尝试是:
(1 to 10).view map {k => (k, f(k))} find {_._2.isDefined}
使用view
可避免创建中间map
。或者更好的模式匹配和部分功能:
(1 to 10).view map {k => (k, f(k))} collectFirst {case (k, Some(v)) => (k, v)}
如果找不到满足Option[(Int, java.lang.String)]
的元素,则返回None
(f
。)
您也可以尝试使用.zipWithIndex
。
答案 1 :(得分:2)
稍短一些 - 只需映射并找到:
// 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)))
答案 2 :(得分:2)
Tomasz Nurkiewicz解决方案稍微冗长的版本:
xs = (1 to 10).view
xs zip { xs map { f(_) } } collectFirst { case (k, Some(v)) => (k, v) }