从scala中的列表[对象,异常]]中筛选出重复项

从scala中的列表[对象,异常]]中筛选出重复项,scala,Scala,我正在处理一个列表,它可以由userInfo对象或 例外。我现在要做的是过滤掉所有重复的用户信息 物体。过滤应该在userInfo中的email属性上完成。 完成后,我希望返回列表的列表[InvitePatternException,UserInfo]] val filtered = list.map { case Success(userInfo) => Right(userInfo) case Failure(ex: InvitePatternException) =>

我正在处理一个列表,它可以由userInfo对象或 例外。我现在要做的是过滤掉所有重复的用户信息 物体。过滤应该在userInfo中的email属性上完成。 完成后,我希望返回列表的列表[InvitePatternException,UserInfo]]

val filtered = list.map {
  case Success(userInfo) => Right(userInfo)
  case Failure(ex: InvitePatternException) => Left(ex)
}
所以我的问题是,我应该如何以及何时执行过滤?我应该在屏幕上过滤吗 列出[InvitePatternException,UserInfo]]或之前的内容?
scala是如何做到这一点的?

这一点在列表中重复了两次: 1.用于筛选出异常 2.用于基于属性删除重复项

Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_65).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class UserInfo(name: String, age: Int, email: String)
defined class UserInfo

scala> case class InvitePatternException(e: String) extends Throwable(e)
defined class InvitePatternException

scala> val eitherList: List[Either[InvitePatternException, UserInfo]] = 
List(
  Right(UserInfo("a",1,"a.mail.com")), 
  Right(UserInfo("b",1,"b.mail.com")), 
  Right(UserInfo("c",1,"a.mail.com")), 
  Right(UserInfo("d",5,"d.mail.com")), 
  Left(InvitePatternException("failed for user with name = d")), 
  Left(InvitePatternException("failed for user with name = e")), 
  Right(UserInfo("e",7,"a.mail.com"))
)

eitherList: List[Either[InvitePatternException,UserInfo]] = List(Right(UserInfo(a,1,a.mail.com)), Right(UserInfo(b,1,b.mail.com)), Right(UserInfo(c,1,a.mail.com)), Right(UserInfo(d,5,d.mail.com)), Left(InvitePatternException: failed for user with name = d), Left(InvitePatternException: failed for user with name = e), Right(UserInfo(e,7,a.mail.com)))

scala> val resultList = eitherList.filter(_.isLeft) ::: eitherList.collect { case Right(userInfo) => userInfo }.groupBy(_.email).map(_._2.head).map(Right(_)).toList
resultList: List[Either[InvitePatternException,UserInfo]] = List(Left(InvitePatternException: failed for user with name = d), Left(InvitePatternException: failed for user with name = e), Right(UserInfo(d,5,d.mail.com)), Right(UserInfo(a,1,a.mail.com)), Right(UserInfo(b,1,b.mail.com)))

我会用与任何其他编程语言大致相同的方法来实现这一点:保留一组您已经看到的内容,如果某个项目位于看到的内容集中,则跳过该项目(下面省略了结果类型以减少噪音):


不要忘记,尽管Scala程序员更喜欢不可变状态,但在最干净的解决方案中使用(本地)可变状态并没有什么本质上的坏处。

但您想保留所有的异常吗?
scala> val items = Seq(
     Right(1), 
     Right(2), 
     Left(new Exception), 
     Left(new Exception), 
     Right(1), 
     Right(3)
)
items = List(Right(1), Right(2), Left(java.lang.Exception), Left(java.lang.Exception), Right(1), Right(3))

scala> val uniques = { 
    var seen = Set[Int](); 
    items.collect { 
      case Left(x) => Left(x); 
      case Right(i) if !seen(i) => 
        seen += i
        Right(i) 
    }
}
uniques = List(Right(1), Right(2), Left(java.lang.Exception), Left(java.lang.Exception), Right(3))