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

时间:2018-06-03 01:13:11

标签: scala

我已经创建了这样的列表列表,我可以根据大小轻松对其进行排序。

@ 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 个答案:

答案 0 :(得分: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)

要使您的示例工作,请在处理elem时提供toSet(请参阅another answer as well)或elem。

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))

答案 1 :(得分: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 points out,您还可以使用.distinct