Scala:递归值listHuman需要类型

时间:2017-05-27 20:54:37

标签: scala recursion functional-programming

为什么这个函数会给我以下错误:

  

递归值listHuman需要类型

def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
    val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).filterNot(a=>listHuman.contains(a))}
    return listHuman
}

我试图这样做,但它给了我另一个错误:

val listHuman: List[Human] = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).get}.filterNot(human=>listHuman.contains(human))
  

前向引用扩展了值listHuman的定义

3 个答案:

答案 0 :(得分:1)

此错误表示在声明之前使用常量值或变量。例如

    val y = x + 2
    val x = 5

您尝试使用自身定义常量值时代码有什么问题。根据{{​​1}}的定义,这是不可能的。要构建递归,请使用constant

答案 1 :(得分:1)

好像你想做一个foldLeft,这有用吗?

def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
  physicalResources.foldLeft(Set.empty[Human]) { (l, pr) =>
    val applicableHuman = totalHumanResources.find(_.handles.contains(pr.post))
    l ++ applicableHuman
  }.toList
}

答案 2 :(得分:0)

此处的前提是setHumanResources返回Human个对象的唯一/干扰列表。代码通过在filterNot(a=>listHuman.contains(a))的定义中执行listHuman来尝试此操作,从而以语义上非法的方式定义listHuman时递归引用listHuman。这种重复数据删除可以通过以下方式正确实现。

  • 将List转换为Set并将其转换回List以删除listHuman.toSet.ToList等重复项。要使此方法起作用,Human对象具有通过覆盖equals方法定义的属性标识。所以代码现在看起来像

    def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
          val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post))
          listHuman.toSet.toList
    }
    

    人类样本类的演示如下所示。

     scala> class Human(val firstName: String, val lastName: String) {
     |   override def toString = this.firstName
     |   override def equals(that: Any): Boolean = that match {
     |      case that: Human if that.firstName == this.firstName => true
     |      case _ => false
     |   }
     | }
    defined class Human
    
    scala> List(new Human("Peter", "Parker"), new Human("Peter", "Quill")).toSet.toList
    res14: List[Human] = List(Peter)
    
  • 如果类Human不能通过重写equals方法在其中定义对象相等性,则遵循此方法。考虑每个Human可以通过两个属性property1property2进行唯一标识。 listHuman可以通过以下表达式重复删除。对于我们之前定义的Human类,如果我们想要对firstName和lastName属性进行重复数据删除,则代码如下所示。

    listHuman.groupBy(x => (x.firstName, x.lastName)).map(_._2.head)
    

    所以新方法定义变为

      def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
           val listHuman = physicalResources.map{pr => 
           totalHumanResources.find(_.handles.contains(pr.post))
           listHuman.groupBy(x => (x.property1, x.property2) ).map(_._2.head)
       }