繁体   English   中英

Scala在递归方法内将项目添加到ListBuffer

[英]Scala add items to ListBuffer inside recursive method

我试图将项目添加到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
}

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

谢谢

三木

您正在进行递归调用,但是您忽略了它的结果。 (实际上,任何时候if没有else ,则if内的表达式仅针对副作用进行评估)。

假设您想要的是追加到filtered ListBuffer的递归调用的结果,则可以将表达式更改为:

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

并摆脱return语句。 (实际上应该避免使用返回语句,永远不要使用它们)。

请注意,这并不是尾递归,它会吹堆栈如果传递到鉴别if是真的太男人次之前,它是假的。 为了使该尾部递归,您可以将递归位设置为内部函数,该函数传递要附加到的列表缓冲区作为递归函数的参数。

创建内部助手方法来对可变集合进行递归通常是最容易的。 像这样:

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM