Scala在递归方法中向ListBuffer添加项目

时间:2014-10-15 10:55:56

标签: scala recursion scala-collections

我试图将项目添加到ListBuffer(或任何其他结构?) 基本上我正在尝试使用此方法创建 PostMD 对象列表。

def getData(url: String, userID: String): ListBuffer[PostMD] = {
  val chunk: JsValue = BusinessLogic.Methods.getJsonValue(url)
  val postMd: List[PostMD] = for {
    x <- (chunk \ "data").as[List[JsValue]]
  } yield x.as[PostMD]

  val filtered: ListBuffer[PostMD] = 
    postMd.filter(_.fromID == userID).to[ListBuffer])

  if ((chunk \ "paging" \ "next").toString() != null) 
    getData(chunk.\("paging").\("next").toString(), userID)

  return filtered
}

显然我做错了什么...... 将项添加到递归方法中的列表的最佳方法是什么?

感谢

miki

2 个答案:

答案 0 :(得分:1)

您正在进行递归调用,但是您忽略了它的结果。 (事实上​​,只要if else没有iffiltered内的表达式就会被评估为副作用。

假设您想要的是附加到ListBuffer if ((chunk \ "paging" \ "next").toString() != null) filtered ++ getData(chunk.\("paging").\("next").toString(), userID) else filtered 的递归调用的结果,那么可能会将您的表达式更改为:

if

摆脱退货声明。 (应该真的避免返回陈述,永远不需要它们。)

请注意,这不是尾递归的,并且如果您传递给{{1}}的鉴别器在其为假之前是真实的话,它将会打击堆栈。为了使这个尾递归,你可以使递归位成为一个内部函数,它将你要附加的列表缓冲区作为递归函数的参数传递。

答案 1 :(得分:1)

创建内部辅助方法以使用可变集合进行递归通常最容易。像这样:

def getData(url: String, userID: String): ListBuffer[PostMD] = {
  val filtered = ListBuffer.empty[PostMD]
  def inner(url: String) {
     val chunk = ...
     val postMD = ...
     filtered ++= postMD.filter(_.fromID == userID)
     val next = (chunk \ "paging" \ "next").toString
     if (next != null) inner(next)
  }
  inner(url)
  filtered
}