当我需要将一个对象的多个参数收集到一个 List 中时,我一直在努力寻找一种方法来保持表达式中的函数风格。

举个例子,假设我有一个 Notification 对象,它有一个 fromId(通知来自的用户 ID)和一个 objectOwnerId(创建原始对象的用户的 ID)。这些在 facebook 样式通知中可能有所不同(“X 也评论了 Y 的帖子”)。

我可以像这样用 for 表达式收集 userIds

val userIds = for { notification <- notifications } yield notification.fromId 

但是说我想将 fromIds 和 objectOwnerIds 收集到一个列表中,有没有办法在没有 vars 用户的情况下在单个 for 表达式中做到这一点?

我过去做过这样的事情:
var ids = List() 
for { 
    notification <- notifications 
    ids = ids ++ List(notification.fromId, notification.objectOwnerId) 
} 
ids = ids.distinct 

但感觉必须有更好的方法。 var 的使用,以及在我完成集合后需要调用 distinct 都是丑陋的。我可以用一些条件来避免不同,但我正在努力学习正确的函数式方法来做事。

在此先感谢您的帮助!

请您参考如下方法:

对于这种情况,有 foldLeft:

(notifications foldLeft Set.empty[Id]) { (set, notification) => 
  set ++ Seq(notification.fromId, notification.ownerId) 
} 

或简写:
(Set.empty[Id] /: notifications) { (set, notification) => 
  set ++ Seq(notification.fromId, notification.ownerId) 
} 

集合不包含重复项。折叠后,您可以根据需要将集合转换为另一个集合。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!