2015-12-15 99 views
1

我有一個方法,我想返回Future[Vector[user]]如何將未來[向量[UserLocation]]轉換爲未來[向量[User]]

方法userLocationService.getUserLocationsInList將返回Future[Vector[UserLocation]]

其中用戶位置看起來像:

case class UserLocation(id: Int, locationId: Int, userId: Int) 


def getUsersInLocation(locationIdList: Set[Int]): Future[Vector[User]] = { 

    userLocationService.getUserLocationsInList(locationIdList).map{ 
     userLocations => 
      // ???????????? 
    } 

} 

我有一個基於用戶ID喜歡返回單個用戶的方法:

userService.getById(userId: Int): Future[User] 

如何建立一個未來[矢量[用戶]鑑於上述?

回答

6

如果mapFuture[Vector[UserLocation]],你可以很容易產生內Vector[Future[User]],從包含的Vector[UserLocation]

userLocations.map(location => userService.getById(location.userId)) 

您可以使用Future.sequence反轉Vector[Future[User]]Future[Vector[User]]

Future.sequence(userLocations.map(location => userService.getById(location.userId))) 

或者使用Future.traverse

Future.traverse(userLocations) { location => userService.getById(location.userId) } 

這會給你一個Future[Future[Vector[User]]],可以通過將map更改爲flatMap來修復。全部放在一起:

def getUsersInLocation(locationIdList: Set[Int]): Future[Vector[User]] = { 
    userLocationService.getUserLocationsInList(locationIdList).flatMap { locations => 
    Future.traverse(locations) { location => 
     userService.getById(location.userId) 
    } 
    } 
} 

或者用換理解:

def getUsersInLocation(locationIdList: Set[Int]): Future[Vector[User]] = { 
    for { 
    locations <- userLocationService.getUserLocationsInList(locationIdList) 
    users <- Future.traverse(locations) { location => 
     userService.getById(location.userId) 
    } 
    } yield users 
} 
+0

對不起! getById返回Future [Option [User]]而不是Future [User]。這會讓事情變得複雜嗎? – Blankman

+0

@Blankman然後你會得到一個'Vector [Option [User]]',你可以直接調用'flatten'。即'yield users.flatten'。 _Assuming_,你只是想丟棄你得到'None'的情況。 –

+0

感謝它的工作,我做了第二個版本,並yield.flatten。出於好奇,我將如何將FlatMap版本中的用戶變得扁平化?我嘗試將所有內容都分配給val並調用users.flatten,但沒有奏效。 – Blankman

相關問題