2017-07-31 104 views
1

我有一个像这样在我的控制器功能:斯卡拉递归循环导致

def getPreviousVersions(id: Int): Action[AnyContent] = Action.async { 
    val result: Future[Option[ElementModel]] = dto.getPreviousVersion(id) 

    // while-loop or whatever is best practice 
    // val arrayOfElements: Future[Seq[ElementModel] = ... 

    val c = for { 
     previousVersions <- arrayOfElements 
    } yield previousVersions 

    //do something with the versions 
    //Return something in the end 
    } 

我的模型看起来是这样的:

case class ElementModel(
            ... 
            previousVersion: Option[Int], 
            ...) 

我的最新previousVersion的ID存储在我的模型。现在,我想要做的是递归迭代或使用while循环或任何最佳实践来获取previousVersion的previousVersion等等。 这个想法是获得所有以前的版本,将它们存储在一个序列中,并将此seq传递给另一个函数。

有没有一种顺利,正确的方法来做到这一点?谢谢!

回答

2
def getVersionSequence(id: Int): Future[List[ElementModel]] = { 

    def _getVersionSequence(id: Int, fList: Future[List[ElementModel]]): Future[List[ElementModel]] = { 
    dto.getPreviousVersion(id).flatMap({ 
     case Some(elementModel) => elementModel.previousVersion match { 
     case Some(pVId) => _getVersionSequence(pVId, fList.map(list => elementModel +: list)) 
     case None => fList.map(list => elementModel +: list) 
     } 
     case None => fList 
    }) 
    } 

    val fInvertedList = _getVersionSequence(id, Future(List.empty[ElementModel])) 

    fInvertedList.map(list => list.reverse) 
} 


def getPreviousVersions(id: Int): Action[AnyContent] = Action.async { 
    val c: Future[List[ElementModel]] = getVersionSequence(id) 

    //do something with the versions 
    //Return something in the end 
} 
+0

这看起来很有希望。但是,当我这样做: getVersionSequence(id).map {elements => Ok(Json.toJson(elements)) } 它返回一个单个对象的数组,虽然此对象有一个属性“previousVersion”。所以我期望在这个数组中有2个对象。许多对象与“previousVersion”不是none/null。 – Nocebo

+0

你确定'previousVersion'链是正确的吗?你是否也计算了currentVersion ...因为这个函数只会返回提供的id的previousVersions? –

+0

你的代码工作得很好。我在我的sql语句中犯了一个错误,我要求另一个属性为true。对不起,非常感谢! – Nocebo

1
def getPreviousVersion(previousVersionId: Int): Future[ElementModel] = dto.getElementModelForId(previousVersionId) 
/*This has been changed from your question, you shouldn't need a getPreviousVersion(id) function in your database connector, but merely a function to get an element by id*/ 

def getAllPreviousVersions(e: ElementModel): Future[Seq[ElementModel]] = { 
    e.previousVersion match { 
     case None => Future.successful(Seq(e)) 
     case Some(id) => getPreviousVersion(id).flatMap { 
     previousVersionElement => 
      getAllPreviousVersions(previousVersionElement).map { 
      //Properly preserves order ! 
      seq => previousVersionElement +: seq 
      } 
     } 
    } 
    } 

def getPreviousVersions(e: ElementModel) = { 

    getAllPreviousVersions(e).map { 

     //do something with the versions 
     //Return something in the end 
     ??? 
    } 
    }