【问题标题】:Scala sortBy Missing parameter type for expanded functionScala sortBy缺少扩展函数的参数类型
【发布时间】:2018-06-03 10:08:38
【问题描述】:

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

@ 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?

【问题讨论】:

    标签: scala


    【解决方案1】:

    在上面的例子中,.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))
    

    【讨论】:

      【解决方案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)
      

      作为prayagupdpoints out,你也可以使用.distinct。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-29
        • 1970-01-01
        • 2017-12-12
        相关资源
        最近更新 更多