2016-09-26 147 views
0

要合併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快嗎?

+0

當你說「更快」,你的意思是「有別人在這個代碼上執行基準測試」?不太可能。然而,第一個例子不需要類型轉換('toList')。 –

+0

我寧願你的第一種方法來解決任何當前的答案。 –

+0

@BobDalgleish是的,我的感覺是,第一個選項的轉換次數較少,因此更可取。 –

回答

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) 

斯卡拉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

怎麼樣一個整潔的理解:

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, [email protected](b)) => sb 
    case ([email protected](a), None) => sa 
    case (Some(a), Some(b)) => Some(a ++ b) 
} 

我認爲這至少創建一個比雙扁平化中間集合少。

+0

不工作,如果任何一個或b是無 – pamu

+0

@ pamu啊,沒有正確閱讀。抱歉。糾正。 –

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. 它返回不正確的類型選項[列表[INT]]而不是選擇[序列[INT]]

  2. 它放在一個& B.不必要調用toList你可以簡單地添加選項並在其上調用flatten

  3. 它是不會幹的,對雙方A.toList & B.toList冗餘呼叫flatten而它可以稱之爲扁平化的(A ++ B)

取而代之的是,你可以更有效地做到這一點:

val E = Option((A ++ B).flatten.toSeq) 
E: Option[Seq[Int]] = Some(List(1, 2, 3, 4)) 
+0

在我的情況下,Option可能是None,所以我不認爲'.get'就足夠了。感謝您澄清第二個案例的問題。 –