尝试从列表中删除所有Unit - ()
时,我尝试拨打toMap
。
scala> List((), ()).filter(_ != ()).toMap
<console>:8: error: Cannot prove that Unit <:< (T, U).
List((), ()).filter(_ != ()).toMap
^
这个错误是什么意思?
对于List
,我想为非Unit元素创建所有元组(String, String)
的映射,但有些值可能为null。
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
^
答案 0 :(得分:4)
啊!现在your other question更有意义了。仍然不确定您在制作此混合Unit
/ Tuple2
列表时所做的工作。
这应该有效:
List((), (), (3,4)).collect { case t@(_: Int, _: Int) => t }.toMap
请注意,我在这里使用variable binding(将匹配绑定到t
)以返回我们匹配的相同Tuple2实例,而不是创建新实例。
使用collect
,您可以将列表类型从List[Any]
转换为List[(Int, Int)]
,这是toMap
想要的,因为它需要一些List[(A,B)]
。< / p>
注意:虽然这个答案对您有用,但我仍然认为您的设计存在缺陷。你最好修复底层设计缺陷,而不是像这样处理这些症状。
看起来这非常适合使用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生成此列表以进行理解,则可以use a guard in your for expression从输出中删除无效元素。
答案 1 :(得分:2)
这意味着列表中元素的类型不能被视为构建Map所需的元组。从某种意义上说,Map是元组的集合(以及更多)。
插图:
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
? ;)
答案 2 :(得分: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)