从三个不同的选项[List [MyType]]制作一个选项[List [MyType]]

时间:2014-08-21 13:32:40

标签: scala

我有

def searchListProducts1 = models.Products.IndivProduct.getProductsFromJsObjectList(productsTextSearchDescription)
def searchListProducts2 = models.Products.IndivProduct.getProductsFromJsObjectList(productsTextSearchName)
def searchListProducts3 = models.Products.IndivProduct.getProductsFromJsObjectList(productsTextSearchIngredients)

其中每个都是Option [List [MyType]]

我想"合并"它们在一起(是折叠吗?)所以我只有一个选项[List [MyType]]

由于

2 个答案:

答案 0 :(得分:3)

正如其他人所建议的,Option[List[T]]是多余的,除非您有充分的理由选择NoneNil。只需丢失Option并执行:

searchListProducts1 ++ searchListProducts2 ++ searchListProducts3

List(searchListProducts1, searchListProducts2, searchListProducts3).flatten

如果你真的想出于某种原因保留Option包装器:

(searchListProducts1 ++ searchListProducts2 ++ searchListProducts3).flatten

List(searchListProducts1, searchListProducts2, searchListProducts3).flatten.flatten

为什么奇怪的双flatten?因为首先将List包装到Option中是很奇怪的。

答案 1 :(得分:0)

一种方式是:

case class MyType(a: Int)

def searchListProducts1: Option[List[MyType]] = ???
def searchListProducts2: Option[List[MyType]] = ???
def searchListProducts3: Option[List[MyType]] = ???

val listed = List(searchListProducts1, searchListProducts2, searchListProducts3)

val merged: Option[List[MyType]] = Option(
  listed.foldLeft(List(): List[MyType])((acc, curr) => curr match {
    case Some(list) => acc ++ list
    case None => acc
  })
)

另一种(我认为更好)方式:

val listed = List(searchListProducts1, searchListProducts2, searchListProducts3)

listed.map(_.getOrElse(List())).reduce(_ ++ _)

但正如LimboSoup所说,我会放弃Option,因为它似乎是多余的,你可以轻松获得一个空列表而不是将其包装在一个选项中。