我有一个选项迭代器,并想找到第一个成员:
- 一些
- 并且满足一个谓词
最好的惯用方法是什么?
另外:如果在此过程中抛出异常,我想忽略它并继续下一个成员
我有一个选项迭代器,并想找到第一个成员:
最好的惯用方法是什么?
另外:如果在此过程中抛出异常,我想忽略它并继续下一个成员
optionIterator find { case Some(x) if predicate(x) => true case _ => false }
至于忽略异常……是谓词 that couldthrow
吗?因为那不是很明智。尽管如此……</p>
optionIterator find {
case Some(x) => Try(predicate(x)) getOrElse false
case _ => false
}
在油漆工作中添加一层最好的和惯用的涂层:
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)
得到第一个超过五的偶数不会破坏测试。
假设您可以包装您的谓词,以便任何错误都返回 false:
iterator.flatMap(x => x).find(yourSafePredicate)
flatMap
获取一个集合的集合(其中一个可迭代的集合Option
被认为是最大大小为 1 的集合)并将其转换为单个集合:Option
Either
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
返回迭代中与谓词匹配的第一个条目,Option
或者None
如果没有匹配项:
scala> (1 to 10).find(_ > 3)
res0: Option[Int] = Some(4)
scala> (1 to 10).find(_ == 11)
res1: Option[Int] = None
一些样本数据
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将产生一个定义值的 Seq,所有的 None 都将被丢弃
scala> l.flatMap(a => a)
res0: Seq[Int] = List(1, -7, 8)
然后在序列上使用find - 您将获得满足谓词的第一个值。请注意,找到的值被包装为选项,导致find在“未找到”的情况下应该能够返回有效值(无)值。
scala> l.flatMap(a => a).find(_ < 0)
res1: Option[Int] = Some(-7)
据我所知,这对 Scala 来说是“OK”的方式。
可能更惯用的方法是在 Seq 上使用collect / collectFirst ...
scala> l.collectFirst { case a@Some(x) if x < 0 => a }
res2: Option[Some[Int]] = Some(Some(-7))
注意这里我们有 Some(Some(-7)) 因为collectFind应该有机会产生“未找到”的值,所以这里 1st Some - 来自 collectFirst,2nd Some - 来自 Option 的 Seq 的源元素。
如果您需要手中的值,可以将 Some(Some(-7))展平。
scala> l.collectFirst({ case a@Some(x) if x < 0 => a }).flatten
res3: Option[Int] = Some(-7)
如果什么也没找到 - 你将拥有 None
scala> l.collectFirst({ case a@Some(x) if x < -10 => a }).flatten
res9: Option[Int] = None