Scala 折叠选项列表以查找第一个或最后一个选项
我试图折叠一个选项列表,以便返回第一个(或最后一个)Some值,如果没有任何Some值,则返回NoneScala 折叠选项列表以查找第一个或最后一个选项,scala,folding,Scala,Folding,我试图折叠一个选项列表,以便返回第一个(或最后一个)Some值,如果没有任何Some值,则返回None scala> val opts = List(None, Some(1), None, Some(2), None) opts: List[Option[Int]] = List(None, Some(1), None, Some(2), None) scala> opts foldLeft(None)((a,io) => a match { case None =>
scala> val opts = List(None, Some(1), None, Some(2), None)
opts: List[Option[Int]] = List(None, Some(1), None, Some(2), None)
scala> opts foldLeft(None)((a,io) => a match { case None => io; case Some(i) =>
a})
<console>:9: error: object None does not take parameters
opts foldLeft(None)((a,io) => a match { case None => io; case Some
(i) => a})
^
scala>val opts=List(无、部分(1)、无、部分(2)、无)
选项:List[选项[Int]]=List(无,一些(1),无,一些(2),无)
scala>选择foldLeft(None)((a,io)=>a匹配{case None=>io;case Some(i)=>
a} )
:9:错误:对象无不接受参数
选择foldLeft(None)((a,io)=>a匹配{case None=>io;case Some
(i) =>a})
^
不知道我做错了什么。另外,可能有一种更简单的方法,使用高阶函数,但我没有注意到。也许这可以解决您的问题-第一个元素:
opts.flatten.headOption
opts.flatten.lastOption
最后一个要素是:
opts.flatten.headOption
opts.flatten.lastOption
展平
方法将取消列表中所有选项
值的装箱,并删除所有无
值headOption
/lastOption
将为列表中的第一个/最后一个元素返回Some
,如果列表为空,则返回None
。非常简单,但对于长列表,它将尝试平展所有内容,因为它并不懒惰。(我认为view
在这方面也帮不了我们,但我不太确定。)
在这种情况下,您可以使用:
opts.dropWhile(_.isEmpty).headOption.flatMap(identity)
不幸的是,我们不能在这里使用flatten
,因为这将返回一个通用的Iterable[Int]
和no选项
,因此我们必须选择较长的惯用语flatMap(identity)
编辑:注意:
会更好。有更好的方法,但要回答提出的问题,你有两个问题 1) 您缺少下面的
选项
。只能使用中缀符号将a.m(b)
转换为a.m b
。foldLeft方法的形式为a.m(b)(c)
。所以要么这样写,要么包含括号(amb)(c)
2) 您需要将None
参数化为选项[Int]
:这里将其解释为None
对象,而不是选项[Int]
实例的值
因此,这将起作用:
opts.foldLeft(None: Option[Int])(
(a,io) => a match { case None => io; case Some(i) => a } )
为什么要这么麻烦
opts.find(_.nonEmpty).flatten
opts.reverse.find(_.nonEmpty).flatten
启动
Scala 2.9
,可以使用提取第一个定义的选项:
List(None, Some(1), None, Some(2), None).collectFirst { case Some(x) => x }
// Option[Int] = Some(1)
这将在第一个定义的选项
处停止迭代,并避免在查找其头部之前展平整个列表
启动您可以使用的Scala 2.13
,这与find
相反(在等待可能的collectLast
?)
似乎find会返回它找到的第一个。有办法找到列表中的第n个或最后一个吗?我认为对于最后一个,您必须在之前反转列表。opts.dropWhile(u.isEmpty)。headOption
返回Option[Option[Int]]
,对吗?!但是为什么双精度选项上的展平
不返回选项[Int]
?根据ev:@PeterSchmitz:ScalaDoc所指的夜间构建,您是正确的。对于2.10,这确实是固定的(当然,除非他们出于某种原因恢复了更改)。另一方面,在Scala 2.9中,在选项
上没有方法展平
——只有隐式转换到Iterable
,在这种情况下执行。@Debilski啊,太好了。我在看夜间文档时感到困惑,因为我的代码(2.9.1)的反应超出了预期。当然,我们应该带上合适的文件;)因为我还在学scala。。。还有没有找到第n个值的方法?@Trevor-opts.view.filter(u.nonEmpty).drop(n-1).headOption.flatte
是一种查找n
第项的方法,而不必整平整个列表。应该指出的是,flatte
将返回列表,而不是像其他答案一样返回选项。@LuigiPlinge您在“n”值的情况下是什么意思?是的,那个例子不起作用。它将抛出一个异常,并返回List
。我把它拿走了。但是答案中的代码按预期返回选项
。嗯,对我来说不是这样,在2.9.0中:它返回Iterable[Int]=List(2)
。从Debilski在问题中的回答来看,这可能是2.9和2.10之间的差异。