4

次のコードは、再帰呼び出しの戻り値の型が Any である限りコンパイルされますが、Any である必要はないため、明らかに何か間違っています。

  case class Group(
    id: Long = -1,
    parentId: Long = -1,
    name: String = "")

  def makeTree(groupId: Long, groups: List[Group]) = {
    def getAllChildren(gid: Long): Any = {
      def children = for {
        g <- groups; if g.parentId == gid
      } yield g

      if (children.isEmpty) List()
      else {
        children map { x =>
          getAllChildren(x.id)
        }
      }
    }
    getAllChildren(groupId)
  }                                               
  val groups = List(Group(1, 0, "A"), 
                    Group(2, 1, "B"), 
                    Group(3, 1, "C"), 
                    Group(4, 2, "D"))

  makeTree(1, groups)
  //Results in: Any = List(List(List()), List())
  }

getAllChildren の署名を次のように変更すると:

def getAllChildren(gid: Long): List[Group]

次に、エラーが発生します。

type mismatch;  found   : List[List[Group]]  required: List[Group]

ここで何が間違っていますか。

4

3 に答える 3

2

children map次のように返されるリストを平坦化すると、コードが機能します。

def makeTree(groupId: Long, groups: List[Group]) = {
  def getAllChildren(gid: Long): List[Group] = {
    def children = for {
      g <- groups; if g.parentId == gid
    } yield g

    if (children.isEmpty) List()
    else {
      val listList = children map { x =>
        x :: getAllChildren(x.id)
      }

      listList.flatten
    }
  }
  getAllChildren(groupId)
}

これが発生する理由は、 List[Group] を取得し、それを a も返す関数にマッピングしてList[Group]、結果として a になるためList[List[Group]]です。そのリストを単純にフラット化するだけで、望ましい結果が得られます。

于 2013-07-12T13:16:19.303 に答える