9

尝试Unit - ()从列表中删除所有内容时,我尝试调用toMap.

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

这个错误是什么意思?

对于 a List,我想(String, String)为非 Unit 元素创建所有元组的映射,但其中一些值可以为空。

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

3 回答 3

4

啊! 现在你的另一个问题更有意义了。不过,仍然不确定你在做什么来产生这个混合Unit/Tuple2列表。

这应该有效:

List((), (), (3,4)).collect { case t@(_: Int, _: Int) => t }.toMap

请注意,我在这里使用变量绑定(将匹配项绑定到t)来返回我们匹配的同一个 Tuple2 实例,而不是创建一个新实例。

通过使用collect您将列表的类型从转换List[Any]List[(Int, Int)],这是toMap想要的,因为它期待一些List[(A,B)]


注意:虽然这个答案应该对你有用,但我仍然认为你的设计有缺陷。您最好修复潜在的设计缺陷,而不是像这样对待症状。

看起来这很适合使用Scala 的Optiontype。在这种情况下,您的示例列表将变为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 生成此列表以进行理解,则可以在 for 表达式中使用保护来从输出中删除无效元素。

于 2013-10-10T18:21:11.403 回答
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?;)

于 2013-10-10T18:14:57.847 回答
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)
于 2013-10-11T13:42:59.653 回答