当一个选项非空时执行某些操作

时间:2017-04-08 20:12:05

标签: scala collections

如果两个选项中只有一个非空,我想计算一些东西。显然这可以通过模式匹配来完成,但有更好的方法吗?

(o1, o2) match {
  case (Some(o), None) => Some(compute(o))
  case (None, Some(o)) => Some(compute(o))
  case _ => None
}

4 个答案:

答案 0 :(得分:3)

你可以这样做:

words <- data.frame(sentence_id=c(1, 1, 2, 2, 2),
                    word_id=c(1, 2, 1, 3, 4))
data_label <- data.frame(sentence_id=c(1, 2), label=c(0, 1))

但模式匹配可能是更好的方法。

答案 1 :(得分:1)

感谢@Suma的有用评论,除了现有的解决方案之外,我想出了另一种解决方案:

由于输入始终采用Option(x)

的形式
Iterator(Seq(o1,o2).filter(_!=None))
  .takeWhile(_.length==1)
  .map( x => compute(x.head.get))
  .toSeq.headOption

使用迭代器还允许将一系列值传递给输入。当且仅当定义了序列中的一个值时,才会完成最终的映射。

答案 2 :(得分:1)

受到现在已删除的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
  }

答案 3 :(得分:0)

只需初始化序列然后展平

Seq(o1, o2).flatten match {
  case Seq(o) => Some(compute(o))
  case _ => None
}