2013-10-10 45 views
6

當試圖從列表中刪除所有Unit -(),席力圖召toMap不能證明單位<<(T,U)

scala> List((),()).filter(_ !=()).toMap 
<console>:8: error: Cannot prove that Unit <:< (T, U). 
       List((),()).filter(_ !=()).toMap 
             ^

這個錯誤是什麼意思?

對於List,我想製作一張非單元元素的所有元組(String, String)的,但是一些值可以爲空。

scala> val x = List((),(), (3,4)).filter(_ !=()).toMap 
<console>:7: error: Cannot prove that Any <:< (T, U). 
     val x = List((),(), (3,4)).filter(_ !=()).toMap 
               ^

scala> val x = List((),(), (3,4)).filter(_ !=()) 
x: List[Any] = List((3,4)) 

scala> x.toMap 
<console>:9: error: Cannot prove that Any <:< (T, U). 
       x.toMap 
       ^

回答

4

啊!現在your other question更有意義。不過不知道你在做什麼,但生產這種混合Unit/Tuple2列表。

這應該工作:

List((),(), (3,4)).collect { case [email protected](_: Int, _: Int) => t }.toMap 

請注意,我用variable binding這裏(比賽結合t)返回匹配的我們,而不是創建一個新的同Tuple2實例。

使用collect您轉換您的清單,從List[Any]List[(Int, Int)]的類型,這是toMap想要的東西,因爲它期待一些List[(A,B)]


注:雖然這個答案應該爲你工作,我仍然認爲你的設計是有缺陷的。你最好修復潛在的設計缺陷,而不是像這樣治療症狀。

看起來這將是一個非常適合使用Scala's Option type。在這種情況下,您的樣本名單將成爲List(None, None, Some((3,4))),或者你可以把它寫成List(None, None, Some(3->4))的可讀性(像括號嵌套可以得到混淆)。

如果您使用Option那麼您的列表的類型將變爲List[Option[(Int, Int)]],這應該比List[Any]更好處理。爲了擺脫None條目,並得到想要的List[(Int,Int)]你可以撥打flatten

List(None, None, Some(3->4)).flatten 
// res0: List[(Int, Int)] = List((3,4)) 
List(None, None, Some(3->4)).flatten.toMap 
// res1: scala.collection.immutable.Map[Int,Int] = Map(3 -> 4) 

然而,這將是更好,如果你能避免將None條目列表第一地點。如果你使用Scala製作這個列表來理解,你可以從輸出中刪除無效的元素。

+0

感謝您指出我的設計缺陷。我使用'None''sb/c,當使用for表達式迭代List [JsObject]時,我需要返回一個字段(我相信)作爲for表達式的yield的一部分。 .')。我的代碼如下所示:'for {jsObj < - jsonObjs; val x = ...'返回類型是List [Option(String,JsValue)]'。是否可以「跳過」表達式中的值?對於我需要跳過的值,我將返回「無」。 –

+1

@Kevin - 是的,你可以跳過數值。這就是我關於在理解中使用警衛的意見。閱讀我鏈接到的博客上的示例,並且應該清楚如何執行此操作。順便說一句,我第一次在Scala編寫理解時遇到了類似的問題。在我學會了如何利用警衛和'Nothing'類型之後,我能夠做很多工作來清理我的代碼! – DaoWen

1

這意味着,在列表中的一個元素的類型不能作爲被構建地圖所需要的元組進行查看。從某種意義上說,地圖是元組(和更多)的集合。

插圖:

scala> List(1).toMap 
<console>:8: error: Cannot prove that Int <:< (T, U). 
      List(1).toMap 
       ^
scala> List(1 -> 2).toMap 
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2) 

我可以建立從元組列表的地圖,而不是從單一的基數元素的列表。

也許你的意思是說.map而不是.toMap? ;)

1

所有一氣呵成:

scala> val l2 = List(1 -> 3,(), 4 -> 4,(), 9 -> 4,(), 16 -> 7) 
l2: List[Any] = List((1,3),(), (4,4),(), (9,4),(), (16,7)) 

scala> (l2 collect { case (a, b) => (a, b) }).toMap 
res4: scala.collection.immutable.Map[Any,Any] = Map(1 -> 3, 4 -> 4, 9 -> 4, 16 -> 7) 

更好類型:

scala> (l2 collect { case (i: Int, j: Int) => (i, j) }).toMap 
res5: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 4 -> 4, 9 -> 4, 16 -> 7) 
+0

因此,如果我只想創建一個'Map [Int,Int]',那麼只需要'更好的類型'答案,對吧? –

+1

你應該儘可能地避免'任何'! –

相關問題