2017-07-31 103 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 
     ??? 
    } 
    }