scala合并选项序列

时间:2016-09-26 19:43:35

标签: scala scala-collections scala-option

想要合并val A = Option(Seq(1,2))val B = Option(Seq(3,4))以产生新的选项序列

val C = Option(Seq(1,2,3,4))

val C = Option(A.getOrElse(Nil) ++ B.getOrElse(Nil))

似乎比

更快,更惯用

val C = Option(A.toList.flatten ++ B.toList.flatten)

但是有更好的方法吗?我是对的,getOrElsetoList.flatten更快更轻?

3 个答案:

答案 0 :(得分:2)

如何理解整洁:

val Empty = Some(Nil)

val C = for {
  a <- A orElse Empty
  b <- B orElse Empty
} yield a ++ b

创建较少的中间选项。

或者,你可以做一些有点麻烦的模式匹配:

(A, B) match {
  case (None, None) => Nil
  case (None, sb@Some(b)) => sb
  case (sa@Some(a), None) => sa
  case (Some(a), Some(b)) => Some(a ++ b)
}

我认为这至少会产生比双重展平更少的中间收藏品。

答案 1 :(得分:0)

使用foldLeft

Seq(Some(List(1, 2)), None).foldLeft(List.empty[Int])(_ ++ _.getOrElse(List.empty[Int]))
result: List[Int] = List(1, 2)

两次使用flatten

Seq(Some(Seq(1, 2, 3)), Some(4, 5, 6), None).flatten.flatten

result: Seq(1, 2, 3, 4, 5, 6)

Scala REPL

scala> val a = Some(Seq(1, 2, 3))
a: Some[Seq[Int]] = Some(List(1, 2, 3))

scala> val b = Some(Seq(4, 5, 6))
b: Some[Seq[Int]] = Some(List(4, 5, 6))

scala> val c = None
c: None.type = None

scala> val d = Seq(a, b, c).flatten.flatten
d: Seq[Int] = List(1, 2, 3, 4, 5, 6)

答案 2 :(得分:0)

你的第一个案例:

// In this case getOrElse is not needed as the option is clearly not `None`.
// So, you can replace the following: 
val C = Option(A.getOrElse(Nil) ++ B.getOrElse(Nil))

// By this:
val C = Option(A.get ++ B.get) // A simple concatenation of two sequences.
C: Option[Seq[Int]] = Some(List(1, 2, 3, 4))

由于多种原因,您的第二个案例/选项有误。

val C = Option(A.toList.flatten ++ B.toList.flatten)

    Option[List[Int]] = Some(List(1, 2, 3, 4)) 
  1. 返回错误类型Option [List [Int]]而不是Option [Seq [Int]]

  2. 在A&amp; A上不必要地调用toList B.您只需添加选项并在其上调用flatten

  3. 这不是DRY,而是在flattenA.toList上冗余调用B.toList(A ++ B)可以在val E = Option((A ++ B).flatten.toSeq) E: Option[Seq[Int]] = Some(List(1, 2, 3, 4))

  4. 上调平

    而不是这样,你可以更有效地做到这一点:

    convert -density 300x300 -quality 100 ./1.pdf ./2.pdf ./merged.pdf"