Scala sortBy函数缺少扩展函数的参数类型

4
我已经创建了一个像这样的列表,我可以根据大小轻松地对其进行排序。
@ List(List(2, 2, 3), List(7)).sortBy(_.size)
res71: List[List[Int]] = List(List(7), List(2, 2, 3))

但是如果我的列表中有重复项,我想要去除这些重复项,可以进行以下操作:

@ List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.toList
res72: List[List[Int]] = List(List(2, 2, 3), List(7))

您可以看到上面列表的数据类型仍然是List[List[Int]]。

现在,如果我尝试

@ List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.toList.sortBy(_.size)
cmd73.sc:1: missing parameter type for expanded function ((x$2: <error>) => x$2.size)
val res73 = List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.toList.sortBy(_.size)
                                                                                          ^
Compilation Failed

我也尝试过。
@ List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.toList.sortBy(x => x.size)
cmd73.sc:1: missing parameter type
val res73 = List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.toList.sortBy(x => x.size)
                                                                                          ^
Compilation Failed

我有点困惑。手动构建的List[List[Int]]和来自toList函数的List[List[Int]]之间有什么区别?为什么我可以在第一个上调用sortBy,但无法在第二个上调用sortBy?

2个回答

2
在上面的例子中,.toSet 会使 List[T] 中的元素类型丢失。
def toSet[B >: A]: immutable.Set[B] = to[immutable.Set].asInstanceOf[immutable.Set[B]]

scala> List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.foreach(x => println(x))
<console>:12: error: missing parameter type
       List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.foreach(x => println(x))
                                                                           ^

但是您可以验证它是否为简单类型T提供正确的类型

scala> List(1, 2, 3, 4, 5, 4, 3, 2, 1).toSet.toList.sorted
res0: List[Int] = List(1, 2, 3, 4, 5)

因此,仅为List[T]指定类型即可实现。

scala> List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.foreach((x: List[Int]) => println(x))
List(2, 2, 3)
List(7)

//set type to toSet
scala> List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet[List[Int]].foreach(x => println(x))
List(2, 2, 3)
List(7)

为使您的示例代码工作,请在处理元素时使用toSet(请参见另一个答案)或为元素指定类型。
scala> List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet.toList.sortBy((x: List[Int]) => x.size)
res2: List[List[Int]] = List(List(7), List(2, 2, 3))

还有,你可以使用.distinct代替.toSet

scala> List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).distinct.sortBy(_.size)
res3: List[List[Int]] = List(List(7), List(2, 2, 3))

2
问题来自于toSet的定义:
def toSet[B >: A]: Set[B]

如你所见,有一个要推断的类型参数。Scala仍然可以在你第一个例子中使用toSet来推断此参数,但涉及Lambda的那个例子具有更复杂的类型推断,Scala显然无法处理。你可以通过为Lambda提供参数类型或更简单地为toSet提供类型参数来修复这个问题。
List(List(2, 2, 3), List(3, 2, 2), List(7)).map(_.sorted).toSet[List[Int]].toList
    .sortBy(_.size)

正如prayagupd所指出的那样,您还可以使用.distinct

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接