2015-12-15 57 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