2016-06-14 54 views
0

我想在結果中使用實際值而不是選項對象。從結果中刪除選項

case class MyObj(id: String, objVal: List[String]) 

val listOfListOfIds = List(List(id1, id2, id3), List(id4, id5, id6)) 

val allMyObjs = List(
    MyObj("id1",List("val1a", "val1b")), 
    MyObj("id2",List("val2a", "val2b")), 
    MyObj("id3",List("val3a", "val3b")), 
    MyObj("id4",List("val4a", "val4b")), 
    MyObj("id5",List("val5a", "val5b")), 
    MyObj("id6",List("val6a", "val6b")) 
) 

listOfListOfIds.map { _.map { id => allMyObjs.find(obj => obj.id == id).map { _.objVal map { v => Future(v) } } } } 

回報List[List[Option[List[scala.concurrent.Future[String]]]]],如何讓List[List[List[scala.concurrent.Future[String]]]]呢?

+1

可以打開一個'選項[列表[T]]'到可能爲空'列表[T]'調用'opt.getOrElse(List.empty [T])'。代碼將受益於使用案例類具有更多顯式類型。 – cchantep

+0

這是你的實際代碼?我想知道如果你想在兩個集合之間進行交集,爲什麼不使用'HashSet'?另外,你可以扁平清單的名單? –

+0

我還建議至少使用中間變量,不可變變量。我相信'List [List [List [scala.concurrent.Future [String]]]]'類型不清楚要理解。 –

回答

1

我會使用一個flatMap而不是地圖:

val res = listOfListOfIds.map { 
    _.flatMap { id => allMyObjs.find(obj => obj.id == id).map { _.objVal map { v => Future(v) } } } 
} 
+0

是的,這是有效的,所以接下來的問題是如何平整所有獲得List [scala.concurrent.Future [String]]而不是List [List [List [scala.concurrent.Future [String]]]],最好的我可以有List [List [scala.concurrent.Future [String]]] – jerome

+1

它是相同的原理flatMap而不是第一張地圖,然後在最後平坦化 – eliasah

1

這裏有一個替代的解決方案。期權的來源是你應用到列表中的find()方法:

allMyObjs.find(obj => obj.id == id) 

由於find()方法可以或不可以,找到你要找的內容,它必須返回一個選項。另一種方法是使用filter(),它將放棄不符合作爲參數傳遞的謂詞的項目,只返回那些可以做的參數。如果改爲使用下面的代碼,結果將與值本身的列表:

> listOfListOfIds.flatMap { _.flatMap { id => allMyObjs.filter(obj => obj.id == id).flatMap {_.objVal map { v => Future (v) } } } } 
res0: List[scala.concurrent.Future[String]] = List(Success(val1a), Success(val1b), Success(val2a), Success(val2b), Success(val3a), Success(val3b), Success(val4a), Success(val4b), Success(val5a), Success(val5b), Success(val6a), Success(val6b)) 

作爲去除中間的列表,你可以使用flatMap()而不是圖(),結合在壓平根據您的喜好結束。

乾杯