【发布时间】:2017-04-08 20:12:05
【问题描述】:
如果两个选项中的一个不为空,我想计算一些东西。显然这可以通过模式匹配来完成,但有更好的方法吗?
(o1, o2) match {
case (Some(o), None) => Some(compute(o))
case (None, Some(o)) => Some(compute(o))
case _ => None
}
【问题讨论】:
标签: scala collections
如果两个选项中的一个不为空,我想计算一些东西。显然这可以通过模式匹配来完成,但有更好的方法吗?
(o1, o2) match {
case (Some(o), None) => Some(compute(o))
case (None, Some(o)) => Some(compute(o))
case _ => None
}
【问题讨论】:
标签: scala collections
你可以这样做:
if (o1.isEmpty ^ o2.isEmpty)
List(o1,o2).flatMap(_.map(x=>Some(compute(x)))).head
else
None
但是模式匹配可能是更好的方法。
【讨论】:
List(o1,o2).map(_.map(compute)).head或List(o1,o2).flatten.map(compute).headOption?
if (o1.isEmpty ^ o2.isEmpty) (o1 orElse o2).map(compute) else None?
感谢@Suma 提供的帮助,我想出了除当前解决方案之外的其他解决方案:
由于输入始终采用Option(x) 的形式:
Iterator(Seq(o1,o2).filter(_!=None))
.takeWhile(_.length==1)
.map( x => compute(x.head.get))
.toSeq.headOption
使用迭代器还允许将一系列值传递给输入。当且仅当定义了序列中的一个值时,才会完成最终映射。
【讨论】:
filter(a => Option(a).isDefined 的用途是什么 - Option(a) 总是被定义,除非 a 是 null。当您已经知道temp 仅具有一个元素时,reduceOption 的目的是什么?这不是和headOption一样吗?我也没有看到代码中的任何地方使用了compute。
compute(temp.headOption.flatten),它必须是temp.head.map(compute)。
compute 的工作原理做出任何假设。我想用什么实现compute 我的代码中断。
compute(x: Int): Int 编译给我 - compute 需要 Option 的内容作为参数,而不是 Option 本身。
asInstanceOf - 它几乎永远不会完成,而是使用提取器 - 如果不确定如何,请查看一些示例。至于“如果输入总是采用 Some(x) 的形式”——是的,o1 和 o2 总是Option(有时是Some,有时是None)。
受pedrofurla 的已删除答案的启发,该答案试图使用o1 orElse o2 map { compute },一种可能性是定义xorElse,其余的很容易:
implicit class XorElse[T](o1: Option[T]) {
def xorElse[A >: T](o2: Option[A]): Option[A] = {
if (o1.isDefined != o2.isDefined) o1 orElse o2
else None
}
}
(o1 xorElse o2).map(compute)
我发现的另一种可能性是使用模式匹配,但使用Seq 连接,以便使用相同的代码处理两种情况。这种方法的优点是它可以扩展到任意数量的选项,它总是会在只有一个时进行评估:
o1.toSeq ++ o2 match {
case Seq(one) => Some(compute(one))
case _ => None
}
【讨论】:
None 类型的变量,而是使用值None 并输入Option。你可以这样测试:o1: Option[Int] = None 或(我更喜欢)o1 = Option.empty[Int]。
只需初始化一个序列,然后展平
Seq(o1, o2).flatten match {
case Seq(o) => Some(compute(o))
case _ => None
}
【讨论】: