我有一个选项迭代器,想找到第一个成员:
最好的惯用方法是什么?
另外:如果一路上抛出异常,我想忽略它并转移到下一个成员
答案 0 :(得分:6)
optionIterator find { case Some(x) if predicate(x) => true case _ => false }
至于忽略异常......这是谓词throw
吗?因为这不是真的明智。尽管如此...
optionIterator find {
case Some(x) => Try(predicate(x)) getOrElse false
case _ => false
}
答案 1 :(得分:3)
为油漆工作添加最佳和惯用的外套:
scala> val vs = (0 to 10) map { case 3 => None case i => Some(i) }
vs: scala.collection.immutable.IndexedSeq[Option[Int]] = Vector(Some(0), Some(1), Some(2), None, Some(4), Some(5), Some(6), Some(7), Some(8), Some(9), Some(10))
scala> def p(i: Int) = if (i % 2 == 0) i > 5 else ???
p: (i: Int)Boolean
scala> import util._
import util._
scala> val it = vs.iterator
it: Iterator[Option[Int]] = non-empty iterator
scala> it collectFirst { case Some(i) if Try(p(i)) getOrElse false => i }
res2: Option[Int] = Some(6)
获得超过5的第一个偶数而且不会爆炸测试。
答案 2 :(得分:1)
假设您可以包装谓词,以便任何错误返回false:
iterator.flatMap(x => x).find(yourSafePredicate)
flatMap
收集集合(其中Option
的可迭代为Option
且Either
被视为最大为1的集合)并将其转换为一个集合:
scala> for { x <- 1 to 3; y <- 1 to x } yield x :: y :: Nil
res30: IndexedSeq[List[Int]] = Vector(List(1, 1), List(2, 1), List(2, 2), List(3, 1), List(3, 2), List(3, 3))
scala> res30.flatMap(x => x)
res31: IndexedSeq[Int] = Vector(1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 3, 3)
find
会返回您的iterable中的第一个条目,如果没有匹配项,则会将谓词与Option
或None
匹配:
scala> (1 to 10).find(_ > 3)
res0: Option[Int] = Some(4)
scala> (1 to 10).find(_ == 11)
res1: Option[Int] = None
答案 3 :(得分:1)
一些示例数据
scala> val l = Seq(Some(1),None,Some(-7),Some(8))
l: Seq[Option[Int]] = List(Some(1), None, Some(-7), Some(8))
在Seq of Options上使用 flatMap 将生成一个已定义值的序列,所有无效将被丢弃
scala> l.flatMap(a => a)
res0: Seq[Int] = List(1, -7, 8)
然后在序列上使用 find - 您将获得满足谓词的第一个值。注意,找到的值被包装为Option,因为 find 应该能够在&#34; not found&#34;的情况下返回有效值(None)值。情况。
scala> l.flatMap(a => a).find(_ < 0)
res1: Option[Int] = Some(-7)
据我所知,它是&#34;好的&#34;斯卡拉的方式。
可能更习惯的方法是在Seq上使用收集 / collectFirst ...
scala> l.collectFirst { case a@Some(x) if x < 0 => a }
res2: Option[Some[Int]] = Some(Some(-7))
注意这里我们有一些(一些(-7)),因为 collectFind 应该有机会产生&#34;未找到&#34;价值,所以这里第一部分 - 来自collectFirst,第二部分 - 来自期权的Seq的源元素。
如果您需要手中的值,可以展平某些(有些(-7))。
scala> l.collectFirst({ case a@Some(x) if x < 0 => a }).flatten
res3: Option[Int] = Some(-7)
如果找不到任何内容 - 您将拥有无
scala> l.collectFirst({ case a@Some(x) if x < -10 => a }).flatten
res9: Option[Int] = None