Lun*_*ore 9 functional-programming scala
任何人都可以帮助这个Scala新手吗?以前,我们在具有以下数量的实体列表中汇总了一些数量:
sum = entities.foldLeft(0.0)(_ + _.quantity)
Run Code Online (Sandbox Code Playgroud)
现在数量是一个Option[Double]
,总和也是.如何使用惯用的Scala转换它?
如果任何实体的数量是None
那么总和也应该是None
.否则总和应该是Some(total)
.
编辑:将此内容放入单元测试中,以便我可以尝试所有答案.请注意,如果任何数量为无,我确实需要结果为无,因为缺少数量意味着我们还没有完成,所以总数应该反映这一点.即使你没有得到正确的答案,如果你帮助引导我或其他人,或者帮助我学习新的东西,我会赞成.
编辑:@ sepp2k赢得了工作解决方案和解释.感谢大家的学习!
您可以使用Option
's flatMap
和map
方法组合两个Option
s,以便结果将是Some(f(x,y))
两个Option
s Some(x)
和/ Some(y)
或None
其他.
entities.foldLeft(Some(0.0):Option[Double]) {
(acco, x) => acco.flatMap(acc => x.quantity.map(_ + acc))
}
Run Code Online (Sandbox Code Playgroud)
编辑以回应您的评论:
这是一个示例用法:
scala> case class Foo(quantity:Option[Double]) {}
defined class Foo
scala> val entities: List[Foo] = List(Foo(Some(2.0)), Foo(Some(1.0)), Foo(None))
scala> entities.foldLeft(Some(0.0):Option[Double]) {
(acco, x) => acco.flatMap(acc => x.quantity.map(_ + acc))
}
res0: Option[Double] = None
scala> val entities: List[Foo] = List(Foo(Some(2.0)), Foo(Some(1.0)))
scala> entities.foldLeft(Some(0.0):Option[Double]) {
(acco, x) => acco.flatMap(acc => x.quantity.map(_ + acc))
}
res1: Option[Double] = Some(3.0)
Run Code Online (Sandbox Code Playgroud)
所以,是的,None
如果有任何实体,它将返回None
.
关于map
和flatMap
:
map
采用f
类型的函数A => B
并返回Some(f(x))
for Some(x)
和None
for None
.
xo.flatMap(f)
其中f
是类型的函数A => Option[B]
和xo
是Option[A]
,返回Some(y)
IFF xo
是Some(x)
和f(x)
是Some(y)
.在其他情况下(即,如果xo
是None
或者f(x)
是None
)返回None
.
所以表达式acco.flatMap(acc => x.quantity.map(_ + acc))
返回y + acc
iff x.quantity
is Some(y)
和acco
is Some(acc)
.如果一个或两个的x.quantity
和acco
都是None
,结果将是无法比拟的.因为这是在折叠内,这意味着对于下一次迭代,值acco
也将是None
,因此最终结果将是None
.
归档时间: |
|
查看次数: |
3272 次 |
最近记录: |